{"record":{"id":"e4a4f2dcae1f2123","repo":"n8n-io/n8n","slug":"workspace-has-no-sandbox","errorCode":null,"errorMessage":"Workspace has no sandbox","messagePattern":"Workspace has no sandbox","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/workspace/sandbox/run-in-sandbox.ts","lineNumber":45,"sourceCode":"\t\t};\n\t};\n}\n\n/**\n * Execute a shell command in the sandbox and wait for completion.\n * Tries `executeCommand` first, falls back to `processes.spawn` + wait.\n *\n * The third argument may be a cwd string (legacy) or {@link RunInSandboxOptions}.\n */\nexport async function runInSandbox(\n\tworkspace: SandboxCommandTarget,\n\tcommand: string,\n\tcwdOrOptions?: string | RunInSandboxOptions,\n): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n\tconst options: RunInSandboxOptions =\n\t\ttypeof cwdOrOptions === 'string' ? { cwd: cwdOrOptions } : (cwdOrOptions ?? {});\n\tconst sandbox = workspace.sandbox;\n\tif (!sandbox) throw new Error('Workspace has no sandbox');\n\n\tif (sandbox.executeCommand) {\n\t\tconst result = await sandbox.executeCommand(command, [], {\n\t\t\tcwd: options.cwd,\n\t\t\tabortSignal: options.abortSignal,\n\t\t});\n\t\treturn { exitCode: result.exitCode, stdout: result.stdout, stderr: result.stderr };\n\t}\n\n\tif (sandbox.processes) {\n\t\tconst handle = await sandbox.processes.spawn(command, {\n\t\t\tcwd: options.cwd,\n\t\t\tabortSignal: options.abortSignal,\n\t\t});\n\t\tconst result = await raceWithAbort(async () => await handle.wait(), options.abortSignal);\n\t\treturn { exitCode: result.exitCode, stdout: result.stdout, stderr: result.stderr };\n\t}\n","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/workspace/sandbox/run-in-sandbox.ts#L27-L63","documentation":"runInSandbox() reads `workspace.sandbox` and throws immediately if it is falsy. The helper exists to run a command in whatever sandbox a workspace provides; a workspace without a sandbox cannot execute anything, so it fails fast with a clear message instead of a confusing 'cannot read property executeCommand of undefined'.","triggerScenarios":"Calling runInSandbox(workspace, cmd) on a Workspace that was constructed without a sandbox, whose sandbox creation returned undefined, or whose sandbox was cleared. Also when a SandboxCommandTarget is passed that never had .sandbox populated.","commonSituations":"Workspace built in sandboxless mode (e.g. a dry-run/local-exec config); sandbox factory threw and the field was left unset; misconfigured workspace preset that omits the sandbox block.","solutions":["Construct the Workspace with a sandbox provider (Daytona/E2B/local) so workspace.sandbox is populated.","Guard before calling: `if (!workspace.sandbox) throw new Error('configure a sandbox')`.","Check the workspace preset/config includes a sandbox definition."],"exampleFix":"// before\nconst ws = new Workspace({ /* no sandbox */ });\nawait runInSandbox(ws, 'ls');\n\n// after\nconst ws = new Workspace({ sandbox: new DaytonaSandbox(opts) });\nawait runInSandbox(ws, 'ls');","handlingStrategy":"validation","validationCode":"function hasSandbox(ws: { sandbox?: unknown }): boolean {\n  return Boolean(ws.sandbox);\n}\nif (!hasSandbox(workspace)) {\n  throw new Error('configure a sandbox before running commands');\n}","typeGuard":"function hasSandbox(ws: unknown): ws is { sandbox: NonNullable<unknown> } {\n  return typeof ws === 'object' && ws !== null && 'sandbox' in ws && Boolean((ws as { sandbox?: unknown }).sandbox);\n}","tryCatchPattern":null,"preventionTips":["Construct Workspace with a sandbox provider in the preset.","Validate workspace.sandbox at agent setup, not per-command.","Centralize sandbox creation so a missing sandbox fails fast at boot."],"tags":["sandbox","workspace","configuration","agents"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}