Fix Scripting Feature Issues
When to Use
- A pre-request script, after-response script, or test script (
pm.*/insomnia.*API) fails, throws, or produces incorrect results. - Errors like
SECURITY_POLICY_VIOLATION,no module is found for "...",Timeout: Running script took too long, orinsomnia object is invalid or script returns earlier than expected. insomnia-scripting-environmentSDK objects (Request,Response,Environment,Variables,Collection,test()) behave unexpectedly.
Architecture (read this first)
Pre-request/after-response/test scripts (the Postman-compatible pm/insomnia API) have three execution paths depending on where the script runs:
| Path | Entry point | Sandboxing |
|---|---|---|
| Electron app (default) | packages/insomnia/src/entry.hidden-window.ts → packages/insomnia/src/scripting/run-script.ts, run in a hidden BrowserWindow (see packages/insomnia/src/main/window-utils.ts) |
AST-based via packages/insomnia/src/scripting/sandbox.ts + script-security-rules.ts + require-interceptor.ts, toggled by context.settings.scriptSandboxEnabled (default on) |
| Electron app, opt-in QuickJS sandbox | packages/insomnia/src/network/concurrency.renderer.ts → packages/insomnia/src/scripting/run-script-quickjs.ts, run in a Web Worker over a WASM QuickJS VM (quickjs-script-engine.ts) |
Gated by settings.useQuickJsScriptSandbox (default off). PoC with a deliberately minimal, hand-rolled insomnia/$ API — not the shared SDK below — with no test()/pm.test(), collectionVariables, vault, cookies, client certificates, or request mutation, and a sendRequest() limited to plain-text bodies |
inso CLI and other Node-runtime callers (e.g. packages/insomnia/src/runtimes/network/network-adapter.node.ts) |
packages/insomnia/src/script-executor.ts (plain AsyncFunction/eval, no Electron) |
None — script-executor.ts never calls sandbox.ts's prepareSandbox, it's a structurally separate implementation. (Don't confuse this with canSandbox = !!process.type in network-adapter.node.ts — that gates plugin request/response hook sandboxing, an unrelated subsystem.) |
The full SDK object model (InsomniaObject, Request, Response, Environment, Variables, Collection, Test, console/send-request shims) lives in packages/insomnia-scripting-environment/src/objects/ and is shared across the Electron (default) and inso/Node paths only — the QuickJS sandbox does not use it.
insomnia-scripting-environment Folder Hierarchy
The SDK package (packages/insomnia-scripting-environment/) is where the pm/insomnia object model lives — start here for any bug about a specific script API's behavior:
insomnia-scripting-environment/
├── src/
│ ├── objects/ # the pm/insomnia API surface — one file per SDK concept
│ │ ├── index.ts # public re-exports
│ │ ├── insomnia.ts # InsomniaObject — the top-level `insomnia`/`pm` instance scripts see
│ │ ├── interfaces.ts # RequestContext, IEnvironment — the context shape passed in/out of a script run
│ │ ├── execution.ts # Execution — pm.execution (setNextRequest, skipRequest, location)
│ │ ├── request.ts # Request, RequestBody — pm.request
│ │ ├── request-info.ts # RequestInfo — pm.info (event name, iteration data)
│ │ ├── response.ts # Response — pm.response
│ │ ├── send-request.ts # pm.sendRequest() implementation
│ │ ├── environments.ts # Environment, Variables — pm.environment / pm.globals
│ │ ├── variables.ts # Variable, VariableList — underlying key/value model shared by environments/collection
│ │ ├── collection.ts # Collection — pm.collectionVariables / folder & collection variable resolution
│ │ ├── folders.ts # Folder, ParentFolders — collection folder hierarchy walked for variable resolution
│ │ ├── properties.ts # PropertyBase, PropertyList — base classes most SDK objects extend
│ │ ├── headers.ts # Header, HeaderList
│ │ ├── cookies.ts # Cookie, CookieJar, CookieList — pm.cookies
│ │ ├── auth.ts # RequestAuth — pm.request.auth
│ │ ├── certificates.ts # Certificate — client cert modeling
│ │ ├── proxy-configs.ts # ProxyConfig, ProxyConfigList
│ │ ├── urls.ts # Url, QueryParam, UrlMatchPattern — URL parsing/manipulation
│ │ ├── console.ts # Console — console.log capture surfaced back to the app
│ │ ├── test.ts # pm.test()/test() handler registration + TestHandler, waitForAllTestsDone
│ │ ├── async-objects.ts # ProxiedPromise — Promise plumbing so async script code can be awaited by the host
│ │ ├── interpolator.ts # template-tag ({{ }}) interpolation used when resolving variable values
│ │ ├── utils.ts # misc helpers (e.g. checkIfUrlIncludesTag)
│ │ └── __tests__/ # tests for selected objects above (request.test.ts, response.test.ts, etc.)
│ └── autocomplete-snippets.json # generated editor autocomplete data — see scripts/generate-autocomplete.ts
├── scripts/
│ └── generate-autocomplete.ts # regenerates autocomplete-snippets.json from the objects/ source (CI-checked)
├── docs/ # TypeDoc-generated API reference (generated from objects/, don't hand-edit)
├── typedoc.json # TypeDoc config for docs/ generation
└── vitest.config.ts # test runner config for `npm test -w insomnia-scripting-environment`
If a bug is about how a script executes (sandboxing, timeouts, hidden window vs. inso), look in packages/insomnia/src/scripting/ (see Architecture above). If it's about what a specific API returns or mutates (pm.request.headers, pm.environment.get(), pm.response.json(), etc.), it's almost always in this package's src/objects/.
For property/method-level detail on any single object above (real signatures, script-facing surface, gotchas), see references/objects/<name>.md in this skill folder — one file per source file in src/objects/ (e.g. references/objects/request.md for request.ts, references/objects/environments.md for environments.ts).
Procedure
- Identify the execution path first — ask/check whether the failure is in the Electron app or
inso. Fixes and even error messages differ per path (see table above). - Reproduce with the narrowest test before touching app code:
- Unit tests for the sandbox/security logic:
(notnpm test -w insomnia -- src/scriptingnpx vitest run src/scripting -w insomnia— Vitest's own CLI already owns-w/--watch, so that form drops into watch mode instead of selecting theinsomniaworkspace.) Relevant files:packages/insomnia/src/scripting/__tests__/sandbox.test.ts,__tests__/script-security-policy.test.ts,__tests__/require-interceptor.test.ts. - SDK object-model unit tests:
npm test -w insomnia-scripting-environment - Full app unit suite (if narrowing further isn't obvious):
npm test -w insomnia
- Unit tests for the sandbox/security logic:
- If the bug only shows up end-to-end (real app, real request lifecycle), run the Playwright smoke tests:
Relevant specs innpm run test:dev -w insomnia-smoke-test -- --grep "pre-request" npm run test:dev -w insomnia-smoke-test -- --grep "after-response"packages/insomnia-smoke-test/tests/smoke/:pre-request-script-features.test.ts,after-response-script-features.test.ts,pre-request-script-window.test.ts. - Locate the fix by symptom (see Notes below for the mapping from error message to file).
- If you change the SDK's public API surface (new/changed methods on
Request/Response/Environment/etc. ininsomnia-scripting-environment), regenerate autocomplete snippets — CI checks this is committed:npm run generate:autocomplete -w insomnia-scripting-environment
Notes
- Common failure patterns and where to look:
SECURITY_POLICY_VIOLATION/ script blocked for usingthis,globalThis,__proto__,constructor, orimport→ AST rule inpackages/insomnia/src/scripting/sandbox.ts(checkSandboxViolations) or the rule lists inscript-security-rules.ts. These are Electron-app-only;insohas no AST sandbox at all.no module is found for "..."→ the module isn't on the allowlist inpackages/insomnia/src/scripting/require-interceptor.ts. Currently allowed:- Full-access Node builtins:
path,assert,url,punycode,querystring,string_decoder,stream,events - Method-restricted Node builtins (some methods throw):
timers(setImmediateblocked),buffer(allocUnsafe/allocUnsafeSlowblocked),util(inherits/debuglogblocked) - Shims:
atob,btoa - External/npm modules:
ajv,chai,cheerio,crypto-js,csv-parse/lib/sync(note: not barecsv-parse),lodash(backed byes-toolkit/compat),moment,tv4,uuid,xml2js - Special-cased:
insomnia-collection/postman-collection(resolves to the SDK's ownCollectionmodule)
Adding a module means adding it here, not just installing the npm package.
- Full-access Node builtins:
Timeout: Running script took too long(Electron app) → default 5000ms inentry.hidden-window.ts:39(data.context.timeout).insomnia object is invalid or script returns earlier than expected.→ thrown when the wrappedAsyncFunctiondoesn't resolve to anInsomniaObjectinstance; check bothrun-script.tsandscript-executor.tssince the same invariant is duplicated in each path.Hidden window "closed unexpectedly" / "froze" / busy errors → restart/health-check race conditions in
packages/insomnia/src/main/window-utils.ts(hiddenWindowIsBusy,createHiddenBrowserWindow).Works in unit tests but not in CI → confirm
npm run generate:autocomplete -w insomnia-scripting-environmentoutput matches the committedautocomplete-snippets.json;test.ymldiffs this file and fails the build if it's stale.
- The script behavior should be as consistent as possible with the original implementation. The implementation is hosted in this repo.
- CI workflows relevant to this feature:
.github/workflows/test.yml(unit tests + autocomplete snippet check, runs on PR/push to develop),.github/workflows/test-e2e.yml(Playwright smoke tests, same triggers). - Success criteria: the targeted vitest/Playwright command passes, and if the SDK surface changed, the autocomplete snippet diff is clean.