mastra-ai/mastra · error · SetupCommandError
${setupError.message}. The sandbox stays usable: this setup
Error message
${setupError.message}. The sandbox stays usable: this setup command is skipped for the rest of the session — retry your command, then fix the setup command in the repository settings or run it manually. What it means
A user-configured repository setup command ran inside the sandbox and exited non-zero. Factory classifies this as a configuration problem (not infrastructure), records the failed command so the next session start can recover, and rethrows a SetupCommandError with guidance appended: the sandbox remains usable and the command is skipped for the rest of the session.
Source
Thrown at mastracode/factory/src/workspace.ts:609
await runTeardownCommand(target, workdir, projectRepository.teardownCommand, {
timeoutMs: DEFAULT_COMMAND_TIMEOUT_MS,
});
} catch (teardownError) {
console.warn('[Mastra Factory] Worktree teardown after setup failure failed', {
orgId: session.orgId,
sessionId: session.sessionId,
projectRepositoryId: session.projectRepositoryId,
error: teardownError instanceof Error ? teardownError.message.slice(-2000) : String(teardownError),
});
}
}
if (setupError instanceof SetupCommandError) {
// The command ran and exited non-zero — a config problem, not an
// infra one. Remember it so the next start recovers, and tell the
// agent what happens next. Infra failures (transport, clone)
// rethrow untouched and retry in full.
recordFailedSetupCommand(session.id, projectRepository.setupCommand);
throw new SetupCommandError(
`${setupError.message}. The sandbox stays usable: this setup command is skipped for the rest of the session — retry your command, then fix the setup command in the repository settings or run it manually.`,
setupError.code,
);
}
throw setupError;
}
}
};
// The session's real sandbox goes straight onto the Workspace. Providers
// own lazy start (`ensureRunning()` inside the first command/process op)
// and dead-VM self-healing, and the composed `onStart` hook runs the repo
// setup + credential install inside that lifecycle. Metadata-only
// resolutions (thread-list polling) construct but never start.
const sessionSandbox: SessionSandbox = requireExec(sessionEntry.sandbox);
const filesystem = new SandboxFilesystem({
id: `sandbox-fs:${workspaceId}`,
sandbox: sessionSandbox,View on GitHub (pinned to 75dd419e61)
Solutions
- Run the setup command manually (locally or in the sandbox) to see the underlying failure and fix it in the repository settings
- Check the original `setupError.message` (prefix of this message) and `setupError.code` (exit code) for the concrete cause
- If a dependency was the issue, fix the lockfile/registry credentials, then retry — the next session start recovers
- If the command is no longer needed, remove or simplify it in the repository settings
Example fix
// before (repo settings setupCommand) npx turbo build --filter=./apps/* // after — pin dependencies and guard optional steps pnpm install --frozen-lockfile && npx turbo build --filter=./apps/* || echo 'setup skipped non-fatal'
Defensive patterns
Strategy: try-catch
Validate before calling
// dry-run the setup command before materializing the workspace
const result = await runInSandbox(session.id, projectRepository.setupCommand, { dryRun: true });
if (result.exitCode !== 0) {
throw new Error(`Setup command will fail (exit ${result.exitCode}): fix it in repository settings first`);
} Try / catch
try {
await createWorkspaceFactory(session);
} catch (e) {
if (e instanceof SetupCommandError) {
// sandbox still usable; command skipped for the session
console.warn(`Setup skipped (${e.code}): ${e.message}. Fix the command or run it manually.`);
return workspaceWithoutSetup(e);
}
throw e; // infra failures rethrow for full retry
} Prevention
- Test the repository setupCommand locally and in a fresh sandbox image before saving it
- Pin dependency versions and lockfiles so installs are deterministic
- Avoid env vars in setupCommand that are not guaranteed in the sandbox
- Keep the setup command idempotent and fast to shrink failure surface
When it happens
Trigger: The project's `setupCommand` (from repository settings) executes during workspace materialization and returns a non-zero exit code, causing SetupCommandError to be re-wrapped in createWorkspaceFactory.
Common situations: Setup script references a missing file, env var, or dependency; package manager install fails due to lockfile drift or private registry auth; script uses a tool not present in the sandbox image; syntax error after editing the setup command in repo settings.
Related errors
- Could not resolve the sandbox home directory. Pass `remoteDi
- Unknown worker resource limit: ${name}.
- MastraFactory: 'sandbox' is now a callback, not an options o
- MastraFactory: 'sandbox' must be a function constructing a M
- commit-failed
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/915b6ccf44d64044.
Report an issue: GitHub.