{"record":{"id":"4938191f7c7b9939","repo":"mastra-ai/mastra","slug":"sandbox-sandbox-id-cannot-run-the-session-set","errorCode":null,"errorMessage":"Sandbox '${sandbox.id}' cannot run the session setup: no executeCommand implementation","messagePattern":"Sandbox '(.+?)' cannot run the session setup: no executeCommand implementation","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/factory/src/sandbox/session-sandbox.ts","lineNumber":227,"sourceCode":"async function writeMarker(sandbox: WorkspaceSandbox): Promise<void> {\n  // Best-effort: a missing marker only re-runs the idempotent setup later.\n  const marker = markerShellPath(sandbox);\n  await sandbox.executeCommand!(`mkdir -p \"$(dirname \"${marker}\")\" && touch \"${marker}\"`).catch(() => {});\n}\n\n/**\n * Run the session setup, marker-guarded: skip when the marker exists (unless\n * the VM is known-fresh), otherwise run and write the marker only on\n * success. Setup failures propagate — no marker is written, so the next\n * attempt re-runs.\n */\nasync function runGuardedSetup(\n  sandbox: WorkspaceSandbox,\n  run: SessionSetupRun,\n  { skipMarkerProbe, sessionId, repoFullName }: { skipMarkerProbe: boolean; sessionId: string; repoFullName: string },\n): Promise<void> {\n  if (!sandbox.executeCommand) {\n    throw new Error(`Sandbox '${sandbox.id}' cannot run the session setup: no executeCommand implementation`);\n  }\n  // Resolved from the live instance (the hook runs inside `start()`, so the\n  // VM is up) and memoized on the session entry for passive readers.\n  const workdir = await resolveSessionWorkdir(sessionId, sandbox, repoFullName);\n  if (!skipMarkerProbe && (await markerPresent(sandbox, workdir))) return;\n  await run(sandbox, workdir);\n  await writeMarker(sandbox);\n}\n\n/**\n * Build the session setup hook, which factory attaches to the constructed\n * sandbox with `setOnStart`. Runs inside the sandbox start\n * lifecycle: a fresh VM (`outcome: 'created'`) runs setup with no probe; a\n * reconnect probes the marker first, which re-runs setup after a failed or\n * crash-interrupted attempt. Throwing fails `start()` loudly — core treats\n * onStart errors as fatal.\n */\nexport function createSessionSetupHook(","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/factory/src/sandbox/session-sandbox.ts#L209-L245","documentation":"runGuardedSetup() executes per-session sandbox setup commands, which require the sandbox to support command execution. If sandbox.executeCommand is undefined (an offline/passive or unimplemented sandbox adapter), the library refuses to run setup rather than silently skipping it. It is thrown while the session-setup hook runs inside start().","triggerScenarios":"Passing a WorkspaceSandbox implementation without an executeCommand method (e.g. a read-only or stub sandbox) to a flow that triggers createSessionSetupHook, so the guarded setup cannot execute any commands.","commonSituations":"Using a local/browse-only sandbox adapter where command execution was intentionally omitted; a custom sandbox implementation missing the executeCommand method; a provider SDK integration that never wired up command execution; refactors that made executeCommand optional in the type.","solutions":["Implement executeCommand on your WorkspaceSandbox adapter so it can exec commands in the workspace.","Use a sandbox implementation that supports command execution (e.g. a local or VM-backed sandbox) for sessions that need setup.","Skip setup-requiring flows for passive sandboxes instead of starting a session setup hook.","If executeCommand is optional in your build, add an explicit capability check before constructing the session sandbox."],"exampleFix":"// before\nconst sandbox: WorkspaceSandbox = { id: 'my-box' }; // no executeCommand\nawait startSession(sessionId, sandbox);\n\n// after\nconst sandbox = await createLocalSandbox({ id: 'my-box' }); // provides executeCommand\nif (!sandbox.executeCommand) throw new Error('Session sandbox requires executeCommand support');\nawait startSession(sessionId, sandbox);","handlingStrategy":"type-guard","validationCode":"// before starting a session that runs setup\nif (typeof (sandbox as WorkspaceSandbox).executeCommand !== 'function') {\n  throw new Error(`Sandbox ${sandbox.id} cannot run session setup; use a command-capable sandbox`);\n}","typeGuard":"function supportsCommands(sandbox: WorkspaceSandbox): sandbox is WorkspaceSandbox & { executeCommand: NonNullable<WorkspaceSandbox['executeCommand']> } {\n  return typeof sandbox.executeCommand === 'function';\n}","tryCatchPattern":"try {\n  await startSession(sessionId, sandbox);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('no executeCommand implementation')) {\n    console.error(`Sandbox '${sandbox.id}' is passive; provision a command-capable sandbox for this flow`);\n  } else throw err;\n}","preventionTips":["Only pass command-capable sandbox adapters into session setup flows.","Keep executeCommand required (not optional) in your WorkspaceSandbox typings if setup is mandatory.","Add a unit test asserting custom sandbox implementations provide executeCommand.","Document which sandbox adapters support exec vs read-only usage."],"tags":["sandbox","missing-implementation","api-misuse","session-setup"],"backgroundTag":"missing-required-method","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}