Skip to content
Use code for 50% offSee plans

Rehearse a Dependency Upgrade Decision With a Breaking Change

Rehearse a Dependency Upgrade Decision With a Breaking Change

Rehearse a dependency upgrade by tracing a changed HTTP-client contract, testing callers and planning release and side-effect recovery.

By PhantomCodeAI Team

TL;DR

  • Use this fictional prompt: an HTTP-client dependency upgrade changes how non-success responses are handled.
  • Keep request and response fixtures stable so the old and new dependency versions can be compared.
  • Keep the previous deployable artifact and dependency lock available for a code rollback.

Practice a behavior change hidden behind a successful build

Use this fictional prompt: an HTTP-client dependency upgrade changes how non-success responses are handled. The old version returned a response object for every status. The new version throws an exception for certain statuses. Your application compiles, but one retry path now behaves differently. Explain how you would validate and release the upgrade.

The scenario is intentionally hypothetical. It does not describe a particular library's release. In a real upgrade, read that library's own migration guide and release notes. The interview skill is tracing a changed contract through the application rather than assuming a successful installation proves compatibility.

Identify the boundary where behavior changed

Start with the old and new call contracts. What value or exception does the dependency produce for success, validation failure, rate limiting, timeout and server error? Which callers inspect the status, and which catch exceptions broadly?

Build a small contract table:

CaseOld application expectationRisk after the hypothetical change
Successful responseParse the bodyUsually unchanged, still verify
Invalid requestReturn useful error to callerGeneric exception may hide details
Rate limitDelay a permitted retryCatch block may retry immediately
Server errorFollow bounded retry policyRetry count may change
TimeoutTreat outcome as uncertainDuplicate effects remain possible

Do not stop at direct imports. A wrapper may translate the new exception for many callers, or a shared catch block may change behavior across several features. Explain how you would locate that boundary and its consumers.

Build a small fixture around the changed contract

Use a local test server or controlled stub that returns the relevant responses. Keep request and response fixtures stable so the old and new dependency versions can be compared. The goal is not to mock away the exact behavior you need to observe.

Test what the application returns to its caller, how many requests it makes and whether it preserves useful error information. A test that only checks that the dependency function was called may miss the regression. Include one case where the upstream operation could have succeeded before the connection failed, so retry reasoning remains explicit.

For an npm project, npm ci documentation describes installing from an existing lockfile without updating it. That supports a reproducible dependency setup; it does not verify application behavior. Keep runtime and installation conditions controlled while testing the actual contract.

Choose an adaptation boundary deliberately

One option is to update every caller to the new behavior. Another is to adapt the dependency behind an existing wrapper so callers retain a stable application contract. Explain why your choice fits the codebase rather than treating wrappers as automatically good or bad.

If you preserve the old contract, make the translation explicit and test it. Do not swallow every exception and manufacture a success-shaped response. If you adopt the new contract, update callers and tests together so one path does not continue expecting the old return value.

Our system design frameworks guide can help organize the tradeoff between localized compatibility and broader cleanup. The exercise is about managing a change boundary, not maximizing the number of files touched.

Plan release and reversal around side effects

A small rollout can reveal production conditions absent from fixtures, but it is not a substitute for meaningful pre-release checks. Observe application errors, upstream request counts, retry behavior and user-visible failures relevant to the changed contract. Define what would make you stop expanding the rollout.

Keep the previous deployable artifact and dependency lock available for a code rollback. Then ask whether the new version changes persistent data or triggers external side effects. If it only changes response handling, reverting code may restore the prior behavior; duplicate requests already sent still need separate investigation.

Do not describe rollback as erasing events that occurred during the bad release. A reverted binary does not undo an external operation. The distinction is especially important when retry behavior is the suspected regression.

Include the wrapper’s error contract in the release notes for your own team. A future maintainer should know whether callers receive normalized responses or dependency-specific exceptions. Otherwise, a later cleanup can remove the adaptation as apparently redundant code and reintroduce the same bug without changing the dependency version.

Rehearse the diagnosis before the recommendation

Have a partner tell you that error rates are unchanged but upstream requests have doubled. Explain what that suggests and what it does not prove. You might inspect retry traces and exception categories before blaming the dependency itself. The same symptom could arise from another concurrent change.

Finish with a concise recommendation: reproduce the contract difference, adapt at a deliberate boundary, test meaningful response cases, release with relevant observations and retain a valid reversal path. Avoid “upgrade and run all tests” as the entire answer.

Use the mock interview strategy guide to repeat the exercise with a different breaking change, such as altered date parsing. You have learned the method when you can identify the new contract and its consequences without depending on this particular HTTP example.