skip to content

Sandbox Scripts

The JavaScript that runs beside a saved request inside a walled environment with its own object model. Interviewers probe it because it is where a collection stops being a form.

part ofAPI & DB clientsoverview, primer and where to startread it →
on this pageshow

explore

questions

16

In a Postman collection, which requests does a script attached to a folder run for?

level: juniorimportance: must knowfreq 72%

answer

  1. Look at where the script hangs, not the request
  2. Nesting decides reach, at any depth
  3. Sub-folders are covered too
  4. The collection root reaches everything beneath it
  5. Nothing is copied into the request

basics

~10 s

A script attached to a Postman folder runs for every request nested beneath it, at any depth, including requests inside sub-folders. It never reaches requests outside that folder.

solid answer

~40 s

The script is stored on the folder itself, not copied into the requests under it, so its reach is decided purely by nesting. Every request beneath that folder — direct children and anything deeper inside sub-folders — runs it as part of its own send, and nothing outside the folder ever sees it. A script on the collection root therefore reaches every request in the collection, and a script on a request reaches only that request. The inherited script does not replace, and is not replaced by, a request's own script: both run. A request added to the folder later is covered immediately, and one moved out silently loses it. Inside a running script, `pm.execution.location.current` names the owner the script hangs on.

go deeper

for a junior

Be ready to say plainly that a folder's script runs for everything nested beneath it, at any depth, and that a request outside the folder is unaffected.

for a middle

Explain that the script stays on the container and is never copied into requests, so membership is live: adding or moving a request changes what runs without editing the request.

for a senior

Show the diagnostic reflex — an unexplained result on a request with an empty script tab means you read the ancestors, and you fix the script where it lives, not in the request.

for a principal

Own the placement call: inheritance buys write-once coverage of a group, and pays for it in discoverability, so the narrowest container that covers the need is the default.

## What "attached to a folder" actually means A Postman **collection** is a document: a tree of requests, with folders as the containers that group them. A script is not a property of a request the way a URL or a method is — the collection file declares an `event` entry on whatever node the script was saved to, and that node can be a request, a folder, or the collection itself. The important consequence is that the script **stays where it was saved**. It is never copied down into the requests underneath it. When a run reaches a request, the runtime gathers the scripts declared on that request *and* on every container above it, and executes them around that one send. So the question "which requests does this script run for?" is not answered by looking at the requests at all. It is answered by looking at **where the script hangs** and asking what sits beneath that point in the tree. ## Reach follows nesting, and only nesting | Script hangs on | Runs for | |---|---| | the collection itself | every request in the collection, at any depth | | a folder | every request nested beneath that folder, including inside its sub-folders | | a sub-folder | only that sub-folder's own subtree | | a request | only that request | Two consequences follow directly, and both come up in interviews: - **Depth does not stop inheritance.** A folder's script applies to a request three levels down just as much as to a direct child. There is no "direct children only" mode. - **Membership is live.** A request added to the folder next week is covered the moment it is added, because nothing was ever copied into the request to keep in sync. Equally, dragging a request out of the folder silently removes the script from its send — the request itself was never edited, so nothing in it changed. ## Nothing is overridden — inherited scripts stack The most common wrong instinct is to treat this like a config override, where the nearest definition wins and the rest are discarded. That is not what happens. A request that has its own script **and** sits under a folder that has one will run **both**. The inherited script is not shadowed, disabled, or replaced by the nearer one; they simply both execute around the same send, ancestors first. Emptying a request's own script tab therefore removes exactly one script from that request's send and leaves everything it inherits untouched. It is worth naming the contrast explicitly, because the two rules live side by side in the same document: **credentials** inherited from a parent resolve to exactly one owner — a single winner is chosen by walking up the tree — whereas **scripts accumulate**. That credential walk is the inherited-credentials subject in its own right; the point here is only that you cannot reason about one from the other. ## Why this is an interview question Because of the failure it produces. Someone opens a request, sees an empty script tab, runs it, and gets a test result — or worse, a failing one — that appears to come from nowhere. Nothing in the request explains it. The candidate who knows the model checks upward immediately; the candidate who does not starts editing the request and gets nowhere, because the request is not where the behaviour lives. A short checklist for that situation: 1. Open each **ancestor** of the request — the folder it sits in, any folder above that, then the collection root — and read the scripts saved on them. 2. Remember that all of the ones you find are running, not just the nearest. 3. From inside a script, read `pm.execution.location.current`, which names the owner of the script that is currently running — useful because the same inherited script body executes under many different requests and you often need to know which level you are looking at. 4. Fix the behaviour **where the script lives**. Editing the request cannot change an inherited script; the edit has to happen on the container that owns it. ## The design tradeoff in one line Inheritance is what makes a folder a useful unit: setup or checks common to a group of requests are written once and apply to the whole group, including future members. The price is **discoverability** — the reader of any single request sees no sign that a parent script exists. That is a real cost, and it is why the container you choose matters: prefer the narrowest one that covers what actually needs the script, rather than hoisting everything to the collection root because it is convenient.

  • If a folder and a sub-folder inside it both carry scripts, which ones run for a request in the sub-folder?
    Both, outer first: the outer folder's script runs, then the sub-folder's, then the request's own. Inheritance stacks down the whole chain rather than stopping at the nearest container, so a request nested three levels deep can execute several scripts around a single send.
  • Does a request added to that folder later have to opt in to the folder's script?
    No. The script lives on the folder, not inside the request, so anything nested beneath it is covered the moment it is added — and moving a request out of the folder silently drops the script from its send. Reach is decided by where the request sits in the tree, not by anything saved on the request.

A rule posted at the front door applies in every room of the house, and a rule posted in one room applies only there — neither cancels the other.

saying these in an interview costs you the question

  • Thinks a folder script covers only its direct children
  • Believes the script is copied into each request when saved
  • Says a request's own script overrides the inherited one
  • Expects to fix inherited behaviour by editing the request
  • Assumes a request must opt in to a parent's script
open as a page

When a Postman sandbox script calls console.log, where does that output actually go?

level: juniorimportance: must knowfreq 68%

basics

~20 s

Nowhere on its own. The sandbox's console dispatches an execution.console event carrying the cursor, the level and the serialised arguments out to whatever host runs the script, and the host decides whether to display it.

open as a page

In a Postman run, in what order do collection, folder, and request scripts execute for one request?

level: middleimportance: must knowfreq 66%

basics

~10 s

Ancestors first: the collection's script, then each folder's from outermost inward, then the request's own. The Postman SDK's EventList.listeners orders inherited listeners ahead of the item's own, and all of them run.

open as a page

Which parts of an outgoing Postman request can a pre-request script change so the edit actually reaches the wire?

level: middleimportance: must knowfreq 56%

basics

~10 s

Five and only five: url, method, headers, body and auth. Those are the mutations the runtime reads back out of a pre-request script; anything else the script assigns is not carried into the send.

open as a page

In a saved Postman collection, which values can an event's `listen` field take, and when does each script run?

level: middleimportance: must knowfreq 62%

basics

~10 s

Exactly two: prerequest, which runs just before the request is handed to the transport, and test, which runs after the reply arrives. No third, post-send listener name exists in the format.

open as a page

A Postman sandbox script uses bare tests[...] and still passes — why isn't that proof it is current API?

level: middleimportance: must knowfreq 62%

basics

~20 s

Postman's sandbox keeps a legacy compatibility layer that warns once per identifier name and then answers normally, so a bare tests[...] assignment running successfully proves only that the shim exists, not that the spelling is current.

open as a page

What does Postman's sandbox actually do with a bare tests["name"] = value assignment in a script?

level: middleimportance: must knowfreq 55%

basics

~20 s

Postman's sandbox converts the legacy tests object at script end: each key becomes String(key), each value becomes Boolean(value), a falsy one gets a fabricated 'expected <value> to be truthy' error, and the results continue the same test index counter.

open as a page

Why is `pm.response` unavailable in a Postman pre-request script, and what is missing from the test hook?

level: juniorimportance: should knowfreq 52%

basics

~10 s

Because no reply exists yet. pm.response is provided only in the test hook, after the send; pm.execution.skipRequest is provided only in the pre-request hook, while the send can still be abandoned.

open as a page

Reading an old Postman script, which identifiers mark it as legacy sandbox globals rather than pm API?

level: juniorimportance: should knowfreq 46%

basics

~20 s

Everything in Postman's current script API hangs off the single pm object, so bare identifiers such as tests, responseCode, responseBody and the postman command object, plus bundled globals like tv4, xml2Json, CryptoJS and underscore, are the legacy spelling.

open as a page

Which logging members does Postman's sandbox console expose, and what actually differs between them?

level: middleimportance: should knowfreq 44%

basics

~10 s

PostmanConsole builds six members: log, warn, debug, info, error and clear. The five logging ones differ only in the level field on the identical execution.console event they dispatch, not in destination, stream or transport.

open as a page

A Postman request fails a test that is not in its own script tab — how do you find the script's owner?

level: seniorimportance: should knowfreq 48%

basics

~10 s

Look up the tree: an unexplained result almost always comes from a script on an ancestor folder or the collection root. Inside a running script, pm.execution.location.current names the owner it hangs on.

open as a page

Why is what you read in Postman's console a rendering of your value rather than the value itself?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Console arguments are serialised at the moment of the call and shipped out of the sandbox. The host renders that serialisation, so you read a snapshot of what crossed the boundary, never the live object itself.

open as a page

A Postman script sets a correlation header and clearly runs, yet the sent request lacks it — why?

level: seniorimportance: should knowfreq 38%

basics

~20 s

Almost always the wrong moment: the script hangs from the test listener, which runs after the send, so the header is written onto a request that already went. Headers are editable from the pre-request hook only.

open as a page

How would you prove an old Postman collection's scripts no longer depend on the legacy sandbox globals?

level: seniorimportance: should knowfreq 34%

basics

~20 s

Add the pragma "use sandbox2"; to each script. That opts the script out of Postman's legacy compatibility layer, so any remaining old identifier is undefined and fails, which is the only proof a passing run cannot give you.

open as a page

When would you hang a Postman script on the collection root rather than on a single folder?

level: principalimportance: should knowfreq 36%

basics

~10 s

Only when every request in the collection genuinely needs it. The root's reach is the entire collection, including requests added later, and nothing inside a request hints that the script exists.

open as a page

Why should a team never let a Postman run depend on console output being seen or acted on?

level: principalimportance: should knowfreq 28%

basics

~20 s

Logging is a message addressed outward, not a channel with delivery semantics. A console call dispatches an event and returns; the host may render it, drop it, or have no display, and the script is never told which.

open as a page