{"record":{"id":"4b530d4269975f4c","repo":"n8n-io/n8n","slug":"daytona-sandbox-this-id-is-not-running","errorCode":null,"errorMessage":"Daytona sandbox \"${this.id}\" is not running","messagePattern":"Daytona sandbox \"(.+?)\" is not running","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/@n8n/agents/src/workspace/sandbox/daytona-sandbox.ts","lineNumber":190,"sourceCode":"\t\tsuper();\n\t\tthis.id = options.id ?? `daytona-sandbox-${randomUUID()}`;\n\t\tthis.timeout = options.timeout ?? 300_000;\n\t\tthis.language = options.language ?? 'typescript';\n\t\tthis.sandboxName = options.name ?? this.id;\n\t\tthis.auth = new DaytonaAuthManager({\n\t\t\tapiUrl: options.apiUrl,\n\t\t\ttarget: options.target,\n\t\t\tstaticApiKey: options.apiKey,\n\t\t\tgetAuthToken: options.getAuthToken,\n\t\t\trefreshSkewMs: options.refreshSkewMs,\n\t\t\tlogger: options.logger,\n\t\t\tsandboxName: this.sandboxName,\n\t\t});\n\t}\n\n\tget instance(): Sandbox {\n\t\tif (!this.sandbox) {\n\t\t\tthrow new Error(`Daytona sandbox \"${this.id}\" is not running`);\n\t\t}\n\t\treturn this.sandbox;\n\t}\n\n\toverride async start(): Promise<void> {\n\t\tif (this.sandbox) return;\n\n\t\tconst client = await this.getDaytona();\n\t\tconst existing = await this.findExistingSandbox(client);\n\t\tif (existing) {\n\t\t\tthis.sandbox = existing;\n\t\t\tawait this.detectWorkingDirectory();\n\t\t\treturn;\n\t\t}\n\n\t\tthis.sandbox = await this.createSandboxOrReattach(client);\n\t\tawait this.detectWorkingDirectory();\n\t}","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/n8n-io/n8n/blob/5ac6606e81f67bb9534255570cd4e86fd8101eee/packages/@n8n/agents/src/workspace/sandbox/daytona-sandbox.ts#L172-L208","documentation":"DaytonaSandbox.instance is a getter that returns the underlying Daytona SDK `Sandbox` object. If `this.sandbox` is null/undefined it throws, because start() either was never called, failed before assignment, or destroy() cleared it. The getter exists to give internal methods a non-null handle without sprinkling null checks at every call site.","triggerScenarios":"Accessing `sandbox.instance` before start() resolved; after start() failed (findExistingSandbox/createSandbox threw) leaving this.sandbox unset; after stop()/destroy() cleared the reference; calling a method that uses `instance` without first ensuring running.","commonSituations":"Calling executeCommand/processes before awaiting start(); a start failure that was swallowed; using the sandbox after stop.","solutions":["Always `await sandbox.start()` before any other operation, and let start errors propagate.","Don't access .instance directly — go through ensureRunning()/executeCommand() which guard state first.","After stop()/destroy(), create a new DaytonaSandbox rather than reusing."],"exampleFix":"// before\nconst sb = new DaytonaSandbox(opts);\nconst info = await sb.instance.getInfo(); // start not awaited\n\n// after\nconst sb = new DaytonaSandbox(opts);\nawait sb.start();\nconst info = await sb.instance.getInfo();","handlingStrategy":"validation","validationCode":"function isStarted(sandbox: { instance?: unknown }): boolean {\n  return Boolean(sandbox.instance);\n}\n// ensure the sandbox is started before any op:\nif (!sandbox['sandbox']) await sandbox.start();","typeGuard":null,"tryCatchPattern":"try {\n  await sandbox.start();\n  return sandbox.instance;\n} catch (e) {\n  if (e instanceof Error && /is not running/.test(e.message)) {\n    // start failed — recreate the DaytonaSandbox\n  } else throw e;\n}","preventionTips":["Always `await sandbox.start()` before any other call.","Don't access .instance directly — use ensureRunning/executeCommand which guard state.","Recreate the sandbox after stop()/destroy() instead of reusing."],"tags":["sandbox","daytona","lifecycle","agents"],"backgroundTag":null,"analyzedSha":"5ac6606e81f67bb9534255570cd4e86fd8101eee","analyzedAt":"2026-08-12T05:26:35.080Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}