mastra-ai/mastra · error

readFile ${path} failed (exit ${result.exitCode}): ${result.

Error message

readFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}

What it means

When the sandbox readFile probe command exits with a non-zero code that is neither EXIT_IS_DIRECTORY nor EXIT_NOT_FOUND, readFile throws this generic Error including the path, exit code, and the shell's stderr. It means the read genuinely failed at the shell level — e.g. permission denial or the base64 utility failing — rather than a missing file or a directory target.

Source

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

      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()}`);
    }
    const buffer = Buffer.from(result.stdout.replace(/\s/g, ''), 'base64');
    if (options?.encoding) {
      return buffer.toString(options.encoding);
    }
    return buffer;
  }

  async writeFile(path: string, content: FileContent, options?: WriteOptions): Promise<void> {
    const abs = await this.resolveAsync(path);
    await this.assertContainedDest(abs, path);
    const b64 = toBuffer(content).toString('base64');
    const dir = posixPath.dirname(abs);
    const mkdir = options?.recursive === false ? '' : `mkdir -p ${shellQuote(dir)} && `;
    if (options?.overwrite === false) {
      // `set -C` (noclobber) makes the redirect itself the exclusivity check —
      // no exists() pre-check that could race with a concurrent writer.
      const result = await this.exec(

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Read the stderr in the message to identify the shell-level cause (permission denied vs command not found).
  2. Fix file permissions in the sandbox (chmod u+r) or run the step as a user with read access.
  3. Ensure the file is not being deleted/rotated concurrently between the existence probe and the read.
  4. Confirm the sandbox image provides base64 (coreutils or busybox applet) — otherwise use a different read mechanism.
  5. If only the existence/permission classification is needed, guard with a stat/list operation instead of reading full contents.

Example fix

// before\nconst data = await fs.readFile('secrets/key.pem');\n// after\ntry {\n  const data = await fs.readFile('secrets/key.pem');\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Permission denied')) {\n    await fs.exec('chmod u+r secrets/key.pem || true');\n  }\n  throw e;\n}
Defensive patterns

Strategy: retry

Validate before calling

const ls = await fs.readDirectory(dirPath); // confirm file is listed and readable\nclassifyPaths(ls);

Type guard

function isReadFailureError(e: unknown): boolean {\n  return e instanceof Error && /^readFile .* failed \\(exit/.test(e.message);\n}

Try / catch

try {\n  const data = await fs.readFile(path);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('failed (exit')) {\n    // inspect e.message for stderr, optionally retry once after chmod/wait\n  }\n  throw e;\n}

Prevention

When it happens

Trigger: readFile on a file the sandbox user lacks permission to read (base64 < file fails with EACCES); a file that exists at probe time but disappears before the redirect; a restricted/base64-less shell environment; I/O errors on the sandbox filesystem.

Common situations: Files created with restrictive modes (chmod 000 or umask issues) by a previous step; read-protected mount points inside the workdir; sandbox images where PATH or busybox applets differ so stderr reveals the real command failure.

Related errors


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