mastra-ai/mastra · error

moveFile -> failed (exit )

Error message

moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}

What it means

This generic Error is raised by SandboxFilesystem.moveFile in its atomic/structured branch when the probe shell script (existence check on src, existence check on dest, then mv) exits with a code that is not the reserved EXIT_NOT_FOUND or EXIT_EXISTS sentinels. Those two codes are translated to FileNotFoundError and FileExistsError; every other non-zero exit (permission failure, mv crossing filesystem boundaries, sandbox degradation) becomes this error with the raw exit code and stderr attached.

Solutions

  1. Inspect the stderr included in the message for the precise shell error.
  2. Confirm the dest parent directory exists as a directory and is writable.
  3. If src and dest are on different sandbox mounts, copy then delete instead of a single mv.
  4. Fix permissions with chmod/chown inside the sandbox or recreate the sandbox.
  5. Catch FileNotFoundError/FileExistsError separately so only unexpected failures reach this branch.

Example fix

// before — dest parent is not writable by the sandbox user
await sandbox.fs.moveFile('/app/tmp.txt', '/root/tmp.txt');

// after — move within a writable directory
await sandbox.fs.moveFile('/app/tmp.txt', '/app/data/tmp.txt');
Defensive patterns

Strategy: try-catch

Validate before calling

// validate src exists and dest is not inside a non-directory path
await sandbox.fs.stat(src);
await sandbox.fs.mkdir(posixPath.dirname(dest), { recursive: true });
if (await sandbox.fs.exists(dest)) {
  throw new Error(`dest already exists: ${dest}`);
}

Type guard

function isFileExistsOrNotFound(e: unknown): boolean {
  return e instanceof FileExistsError || e instanceof FileNotFoundError;
}

Try / catch

try {
  await sandbox.fs.moveFile(src, dest, { noOverwrite: true });
} catch (e) {
  if (isFileExistsOrNotFound(e)) {
    // handled typed outcomes (dest taken / src missing)
    return;
  }
  throw e; // unexpected exit code; message carries sandbox stderr
}

Prevention

When it happens

Trigger: Calling sandbox.files.moveFile(src, dest, options) where the multi-line probe-and-move script fails: the parent directory of dest cannot be created or written, the src cannot be read/renamed, or the shell itself fails partway through the joined script.

Common situations: Moving a file into a directory owned by another sandbox user; moving across mounts where mv must fall back to copy and fails; stale sandbox state after a snapshot restore; dest parent is actually a file, not a directory.

Related errors


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

Appendix: source

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

    await this.assertContainedDest(destAbs, dest);
    if (options?.overwrite === false) {
      // `mv -n` exits 0 even when it skips, so detect a skipped move by the
      // source surviving. The no-clobber rename itself is atomic; no racy
      // exists() pre-check.
      const result = await this.exec(
        [
          `src=${shellQuote(srcAbs)}`,
          `dest=${shellQuote(destAbs)}`,
          `if [ ! -e "$src" ] && [ ! -L "$src" ]; then exit ${EXIT_NOT_FOUND}; fi`,
          `mkdir -p ${shellQuote(posixPath.dirname(destAbs))} || exit 1`,
          `mv -n "$src" "$dest" 2>/dev/null || exit 1`,
          `if [ -e "$src" ] || [ -L "$src" ]; then exit ${EXIT_EXISTS}; fi`,
        ].join('\n'),
      );
      if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);
      if (result.exitCode === EXIT_EXISTS) throw new FileExistsError(dest);
      if (result.exitCode !== 0) {
        throw new Error(`moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
      }
      return;
    }
    const result = await this.exec(
      `if [ ! -e ${shellQuote(srcAbs)} ]; then exit ${EXIT_NOT_FOUND}; fi; mkdir -p ${shellQuote(posixPath.dirname(destAbs))} && mv ${shellQuote(srcAbs)} ${shellQuote(destAbs)}`,
    );
    if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(src);
    if (result.exitCode !== 0) {
      throw new Error(`moveFile ${src} -> ${dest} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
    }
  }

  // ── Directory operations ───────────────────────────────────────────────

  async mkdir(path: string, options?: { recursive?: boolean }): Promise<void> {
    const abs = await this.resolveAsync(path);
    await this.assertContainedDest(abs, path);
    const flag = options?.recursive === false ? '' : '-p ';

View on GitHub (pinned to 75dd419e61)