In a Postman run, a chained id arrives empty in the next request - how do you find where it was lost?
answer
- Walk the chain forwards, do not guess
- Did the script even reach the write?
- An undefined stores without complaint
- Check the scope you wrote into is tracked
- Inspect the store from the dependent request
basics
~20 sWalk the chain in order: prove the script ran, prove it read a real value out of the reply, prove it wrote into globals, environment or collectionVariables, and prove the value is still there when the next request is built.
solid answer
~40 sFour checkpoints, in order, and do not skip to the end. **Did the script run at all** — a throw earlier in the script, or a transport failure that leaves no response to test, means the `set` line never executed. **Did it read a real value** — `undefined` stores as happily as an id, so check the field was actually in the reply before it was stored. **Did it write into a tracked scope** — `pm.variables.set` is the classic dead end, because the runtime carries back only globals, environment and collection variables. **Is the value still there later** — read the store at the start of the dependent request and confirm nothing unset or replaced the name in between. In practice most broken chains are checkpoint two or three.
code
javascript · 9 linesconst body = pm.response.json();
pm.test('order id present', function () {
pm.expect(body).to.have.property('id');
});
if (body.id) {
pm.collectionVariables.set('orderId', body.id);
}go deeper
Be ready to check the obvious two things first: that the script actually stored something, and that the name it stored matches the name the next request asks for.
Explain why storing undefined is silent, and why a value read back inside the writing script proves nothing about whether it survived the execution.
Demonstrate an ordered diagnosis rather than a hunt - script ran, value real, scope tracked, value still present - and know which checkpoint the majority of real failures land on.
Own the prevention: a convention that every chained write is asserted before it is stored and cleared when the flow ends, so failures surface where they happen and reruns cannot lie.
## Diagnose in chain order, not in panic order The instinct when a request sends an empty value is to look at that request. That is the wrong end. The request is the **victim**; the fault is upstream, in the handoff. Work the chain forwards and each checkpoint eliminates a whole class of cause: 1. **Did the writing script execute?** 2. **Did it obtain a real value?** 3. **Did it write into a scope the runtime carries back?** 4. **Was the value still present when the dependent request was built?** Answer those four in order and you will land on the cause almost every time, because they are mutually exclusive and cover the whole path. ## Checkpoint one — did the script run A test script only runs when there is a response to test. A transport failure upstream means the script never executes, so nothing is written and nothing is carried back. Equally, a throw earlier in the same script — a property read on a body that was not the shape you expected — abandons the rest of it, and the `set` line below the throw simply never happens. The tell here is that the failing request is not the first symptom in the run: something above it already went wrong and you skimmed past it. ## Checkpoint two — did it obtain a real value This is the checkpoint people skip, and it produces the most confusing failures. Storing `undefined` is not an error. The call succeeds, the store now holds a key, and the run continues cheerfully until the dependent request sends nothing useful. Every renamed field, every payload wrapped one level deeper than you assumed, and every reply that returned an error body with a perfectly valid shape lands here. The fix is structural rather than diagnostic: assert the field is present **before** storing it, so the run fails on the request that actually has the problem instead of the one after it. ## Checkpoint three — was the scope a tracked one The runtime collects script writes for three scopes only — globals, environment and collection variables. A write through `pm.variables.set` goes into an execution-local layer that is discarded when the script ends. What makes this so persistent a bug is that it is invisible from inside the script that made it: read the name straight back on the next line and the value is there. | What you observe | Checkpoint two (stored `undefined`) | Checkpoint three (untracked scope) | |---|---|---| | Reading the name back in the writing script | returns `undefined` | returns the value | | The name exists in the store afterwards | yes, with an empty value | no, nothing was carried back | | Where the real fault is | the reply, or the path into it | the choice of `set` call | Those two look identical from the failing request and are told apart in one step: inspect the store from the **dependent** request, not from the one that wrote it. ## Checkpoint four — was it still there If the name is in the store and holds a real value, the remaining possibilities are that something between the two requests removed or replaced it, or that the two sides disagree about the name. Read the store at the start of the dependent request and compare the exact spelling against what the script wrote. ## Instrumentation that repays itself - **Assert before you store.** One assertion on the field turns a downstream mystery into a local failure. - **Never store a value you have not checked.** A guard around the `set` is cheaper than a diagnosis. - **Inspect from the far side.** Any check made inside the writing script proves nothing about whether the value survived. - **Clean up at the end of the flow.** Unset the chained names, so a leftover from an earlier pass cannot make a broken write look like a working one. ## Why a rerun can lie to you The worst version of this bug is the chain that passes on a rerun and fails from clean. That is the signature of a leftover: the dependent request is reading a value an **earlier** pass wrote, and the current pass's broken write is invisible because the store was never emptied. Any diagnosis you trust has to start from a store with the chained names cleared — otherwise you are testing the residue of the last run rather than the behaviour of this one.
- How do you stop a chain from silently storing `undefined`?Assert the field before you store it, and guard the write. Then a missing or renamed field fails the request that actually has the problem, instead of the request one step later that sends an empty value. A chain that stores whatever it happened to find will always report its failure in the wrong place.
- Why is a chain that passes on a rerun but fails from clean suspicious?Because it is probably reading a leftover from the previous pass rather than the value this pass wrote. Unset the chained names when a flow ends, and start any diagnosis from a cleared store, so residue cannot make a broken write look healthy. A chain that only works the second time is not working at all.
saying these in an interview costs you the question
- Blames the dependent request instead of checking the write
- Assumes an empty value means the server returned nothing
- Never checks whether the writing script executed at all
- Stores undefined and reports the chain as working
- Reruns repeatedly instead of instrumenting the handoff
- Verifies the value only from inside the script that wrote it