mastra-ai/mastra · error

${context} failed (exit ${result.exitCode}): ${result.stderr

Error message

${context} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}

What it means

This is the sandbox's generic wrapper for any shell command it runs (writes, appends, deletes, mkdir, rmdir, init) that exits non-zero. It surfaces the exit code plus whatever the shell reported on stderr (or stdout) so the underlying sandbox failure is visible. It is not a distinct error class — the `context` prefix identifies which operation failed.

Source

Thrown at mastracode/sdk/src/agents/sandbox-filesystem.ts:240

   * we check its realpath; for a not-yet-existing target we check the realpath
   * of its nearest existing ancestor directory, since a symlinked parent is the
   * escape vector (e.g. `link -> /etc` then writing `link/passwd`).
   */
  private async assertContainedDest(abs: string, inputPath: string): Promise<void> {
    // First check the target itself (covers overwriting an existing symlink).
    await this.assertContainedRealpath(abs, inputPath);
    // Then check the parent directory's realpath; readlink -f resolves the
    // nearest existing ancestor when the leaf doesn't exist yet.
    const parent = posixPath.dirname(abs);
    if (parent && parent !== abs) {
      await this.assertContainedRealpath(parent, inputPath);
    }
  }

  private async execOk(script: string, context: string): Promise<SandboxCommandResult> {
    const result = await this.exec(script);
    if (result.exitCode !== 0) {
      throw new Error(`${context} failed (exit ${result.exitCode}): ${result.stderr.trim() || result.stdout.trim()}`);
    }
    return result;
  }

  // ── File operations ────────────────────────────────────────────────────

  async readFile(path: string, options?: ReadOptions): Promise<string | Buffer> {
    const abs = await this.resolveAsync(path);
    await this.assertContainedRealpath(abs, path);
    // Guard clauses first: redirecting from a directory "succeeds" with empty
    // output on some shells, so classify before reading.
    const result = await this.exec(
      `if [ -d ${shellQuote(abs)} ]; then exit ${EXIT_IS_DIRECTORY}; elif [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; base64 < ${shellQuote(abs)}`,
    );
    if (result.exitCode === EXIT_IS_DIRECTORY) throw new IsDirectoryError(path);
    if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);
    if (result.exitCode !== 0) {
      throw new Error(`readFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Read the `context` prefix and the captured stderr in the message to identify the failing operation and shell error
  2. Verify the sandbox session/workdir is initialized and writable (run init or a probe write)
  3. Fix the environment: free disk space, correct volume permissions, or install missing shell utilities in the sandbox image
  4. Adjust the target path (e.g. ensure parent directories exist, or remove the file before recreating it)

Example fix

// before
await fs.writeFile('missing-dir/file.txt', 'hi'); // shell write fails, exit != 0
// after
await fs.mkdir('missing-dir');
await fs.writeFile('missing-dir/file.txt', 'hi');
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the parent directory exists and the sandbox is writable before writing
const parent = targetPath.replace(/\/[^/]+$/, '');
await fs.mkdir(parent); // mkdir itself reports a clear context if it fails
const probe = await fs.writeFile(`${parent}/.probe`, '');
await fs.deleteFile(`${parent}/.probe`);

Try / catch

try {
  await fs.writeFile(path, data);
} catch (err) {
  if (err instanceof Error && / failed \(exit \d+\):/.test(err.message)) {
    const context = err.message.split(' failed ')[0];
    const detail = err.message.slice(err.message.indexOf(': ') + 2);
    console.error(`Sandbox op '${context}' failed: ${detail}`); // retry once on transient errors
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Any of writeFile, appendFile, deleteFile, mkdir, rmdir, or init executes a composed shell script in the sandbox that returns a non-zero exit code — e.g. `mkdir -p` hitting a read-only volume, `rm` failing on a protected path, or the init script failing because the workdir is unavailable.

Common situations: Read-only or full filesystem in the sandbox/container; missing shell utilities in minimal images; sandbox session expired or not started before file operations; permissions/ownership mismatches on mounted volumes; writing into a path whose parent is a file rather than a directory.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/36ef7aa33887ecaa. Report an issue: GitHub.