mastra-ai/mastra · error
deleteFile ${path} failed (exit ${result.exitCode}): ${resul
Error message
deleteFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()} What it means
This generic Error is thrown by SandboxFilesystem.deleteFile when the underlying shell `rm` command inside the sandbox exits with a non-zero code that is not the reserved EXIT_NOT_FOUND sentinel. The library already maps 'file does not exist' to FileNotFoundError; any other failure (permissions, directory not empty, read-only filesystem, sandbox daemon issues) surfaces as this raw exit-code/stderr message. The stderr from the sandbox shell is included so the developer can see the actual `rm` failure reason.
Source
Thrown at mastracode/sdk/src/agents/sandbox-filesystem.ts:315
async deleteFile(path: string, options?: RemoveOptions): Promise<void> {
const abs = await this.resolveAsync(path);
// Contain the parent's realpath: deleting `link/file` where `link` points
// outside the workdir must fail, while deleting a symlink entry itself
// (which lives inside the workdir) stays allowed.
await this.assertContainedRealpath(posixPath.dirname(abs), path);
if (options?.force) {
// `rm -f` already succeeds for a missing file, but still fails for
// directories and permission errors — surface those.
await this.execOk(`rm -f ${shellQuote(abs)}`, `deleteFile ${path}`);
return;
}
const result = await this.exec(
`if [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; rm ${shellQuote(abs)}`,
);
if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);
if (result.exitCode !== 0) {
throw new Error(`deleteFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);
}
}
async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {
const srcAbs = await this.resolveAsync(src);
const destAbs = await this.resolveAsync(dest);
await this.assertContainedRealpath(srcAbs, src);
await this.assertContainedDest(destAbs, dest);
const recursive = options?.recursive ? '-r ' : '';
if (options?.overwrite === false) {
// Atomic no-clobber: directories claim the destination with an exclusive
// mkdir; files copy to a temp name then hardlink into place (link(2)
// fails if the destination exists). 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`,View on GitHub (pinned to 75dd419e61)
Solutions
- Read the stderr in the message to identify the exact shell failure (e.g. 'Permission denied', 'Is a directory', 'Read-only file system').
- If deleting a directory, use the directory-removal API or an empty-directory path instead of deleteFile, since rm is called without -r.
- Fix permissions inside the sandbox (chmod/chown the parent directory) or run the sandbox with sufficient privileges.
- Check that the sandbox volume is writable and not full (df, mount flags).
- If the path may not exist, catch FileNotFoundError separately so only true failures hit this error.
Example fix
// before — may delete a directory and fail
await sandbox.fs.deleteFile('/tmp/data');
// after — check kind first or use recursive removal API
const stat = await sandbox.fs.stat('/tmp/data');
if (stat.isDirectory) {
await sandbox.fs.rmdir('/tmp/data', { recursive: true });
} else {
await sandbox.fs.deleteFile('/tmp/data');
} Defensive patterns
Strategy: try-catch
Validate before calling
// check kind and writability before deleting
const stat = await sandbox.fs.stat(path); // throws FileNotFoundError if missing
if (stat.isDirectory) {
throw new Error(`${path} is a directory; use the directory removal API`);
} Type guard
function isFileNotFoundError(e: unknown): e is FileNotFoundError {
return e instanceof FileNotFoundError;
} Try / catch
try {
await sandbox.fs.deleteFile(path);
} catch (e) {
if (isFileNotFoundError(e)) return; // already gone
console.error(`deleteFile failed: ${(e as Error).message}`);
throw e;
} Prevention
- Stat the path first and route directories to the directory-removal API.
- Catch FileNotFoundError explicitly so only true shell failures hit the generic path.
- Keep sandbox volumes writable and monitor free space.
- Avoid deleting files under paths owned by other users in the sandbox.
When it happens
Trigger: Calling sandbox.files.deleteFile(path) where the sandboxed `rm` fails with an unexpected exit code: path exists but is a non-empty directory (rm without -r), the process lacks write permission on the parent directory, the file is a mount point or busy, or the sandbox filesystem layer is degraded.
Common situations: Attempting to delete a directory instead of a file; deleting a file owned by another user inside the sandbox; a read-only or full sandbox volume; deleting a file that a running process in the sandbox still holds on some filesystems (EBUSY); symlink/permission oddities from a previous partial setup.
Related errors
- copyFile ${src} -> ${dest} failed (exit ${result.exitCode}):
- moveFile ${src} -> ${dest} failed (exit ${result.exitCode}):
- pull-failed
- Sandbox workspace root resolution returned an empty path
- Path escapes workspace root: ${inputPath}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/2e498c205ebc7ae2.
Report an issue: GitHub.