Variable Scope and Precedence: Request, Environment, and Global Values in Insomnia
Quick answer: Insomnia resolves a variable name by searching scopes in a defined order, and the narrowest scope wins. When the same name appears in a request, an environment, and a global value, you need to know which one actually gets used or you will debug the wrong layer. Keep names unique where possible, treat the active environment as the operational switch, and avoid relying on global variables for values that differ between environments. The precedence table below is the fastest way to reason about a value that does not look right.
The scopes and what each is for
Insomnia separates values by how broadly they apply. Request-level values belong to a single request, environment values belong to a named context such as staging or production, and global values apply everywhere regardless of the active environment. This layering is useful when used deliberately, but it creates ambiguity the moment the same name is defined in more than one layer, because the resolution happens silently and the editor may not show which source won.
| Scope | Reach | Best used for |
|---|---|---|
| Request / local | One request | Ad hoc override, one-off value |
| Environment | Active environment only | Per-context URLs, IDs, tokens |
| Global | All environments | Truly constant values |
How precedence resolves
The general rule is that the narrowest definition wins. A request-level override takes precedence over the environment, and the environment takes precedence over a global value. If the active environment does not define the name, the lookup falls through to the next layer, which is why a value can appear to come from nowhere when the environment is missing a key and the global silently supplies it.
// Global: applies everywhere
{ "apiVersion": "v2" }
// Staging environment: wins over global for baseUrl
{ "baseUrl": "https://staging.api.example.com" }
// Request override: wins for this request only
// baseUrl resolves to the local override, not staging
{ "baseUrl": "http://127.0.0.1:8080" }
// apiVersion is not defined in the environment,
// so it falls through to the global "v2".
Why duplicates cause the worst bugs
A name that exists in two layers is where the genuinely confusing failures happen. Switching environments may not change a value that you expected to switch because a global or request override is still winning, and the token sent to production can silently remain the staging token. The defensive rule is to keep environment-specific names out of the global layer and to remove request overrides after the debugging session that created them, so they do not linger and override the intended value.
Using environments as the operational switch
The cleanest mental model treats the active environment as the single switch that changes where requests go, with globals reserved for constants that genuinely never change. Keep the same set of keys in every environment so switching cannot leave a value undefined, and put secrets in the environment layer where they can be injected rather than in a shared global that broadens their exposure. Symmetric keys across environments also make a missing value fail loudly instead of being silently covered by a global.
Inspecting the resolved value
When a request behaves unexpectedly, do not guess from the variable syntax. Inspect the rendered request and confirm the concrete value that was sent, then trace that value back to the scope that supplied it. This short loop separates a precedence problem from a real API failure: if the rendered value is wrong, the fix is in the scope definitions, not the request body or the server.
How an agent mishandles it
An agent that encounters a wrong value often adds another definition at a narrower scope to force the result, which deepens the overlap and makes the next environment switch even harder to predict. Ask it to identify the currently winning source, remove the duplicate, and leave one authoritative definition. If the agent hardcodes a URL to escape the resolution chain, reject that: the goal is a predictable scope model, not a value that bypasses the environment switch entirely.
A naming convention that prevents collisions
Beyond knowing the precedence, the easiest way to avoid scope bugs is to reduce the overlaps in the first place with a naming convention. Prefix environment-specific keys with their domain and keep globals reserved for constants, so a glance at the name tells you where it is defined. This makes a duplicate obvious during review and discourages dropping a per-environment value into the global layer, which is the move that most often causes the wrong token to reach production.
// Global: clearly a constant, no per-environment value
{ "global_api_version": "v2" }
// Environment: domain-prefixed, switched by the active environment
{ "billing_base_url": "https://staging.api.example.com" }
{ "billing_token": "staging-injected-token" }
Pair the convention with a check that every environment defines the same set of keys, so switching contexts cannot leave a value undefined and fall through to a global. Symmetric environments and distinctive names make the precedence model easy to trust, rather than something you have to re-derive on every confusing request.
Frequently asked questions
Which value wins when a name is defined in several scopes?
The narrowest scope wins: a request override beats the environment, and the environment beats a global. If the narrower layer lacks the key, the lookup falls through to the next layer.
Why does switching environments not change my value?
Because a request override or a global with the same name is still taking precedence. Remove the duplicate and keep one authoritative definition per environment.
What belongs in the global scope?
Only constants that never change across environments. Anything per-context, including base URLs and tokens, should live in the environment layer.
How do I find the source of a wrong value?
Inspect the rendered request to see the concrete value, then trace it back to the scope that supplied it instead of reasoning from the variable syntax alone.
This is part of the Powerduck vs Insomnia: API Client and Contract Testing — start there for the full comparison of managing variables and contract tests.