{"record":{"id":"2e498c205ebc7ae2","repo":"mastra-ai/mastra","slug":"deletefile-path-failed-exit-result-exitcode","errorCode":null,"errorMessage":"deleteFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}","messagePattern":"deleteFile (.+?) failed \\(exit (.+?)\\): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/agents/sandbox-filesystem.ts","lineNumber":315,"sourceCode":"\n  async deleteFile(path: string, options?: RemoveOptions): Promise<void> {\n    const abs = await this.resolveAsync(path);\n    // Contain the parent's realpath: deleting `link/file` where `link` points\n    // outside the workdir must fail, while deleting a symlink entry itself\n    // (which lives inside the workdir) stays allowed.\n    await this.assertContainedRealpath(posixPath.dirname(abs), path);\n    if (options?.force) {\n      // `rm -f` already succeeds for a missing file, but still fails for\n      // directories and permission errors — surface those.\n      await this.execOk(`rm -f ${shellQuote(abs)}`, `deleteFile ${path}`);\n      return;\n    }\n    const result = await this.exec(\n      `if [ ! -e ${shellQuote(abs)} ]; then exit ${EXIT_NOT_FOUND}; fi; rm ${shellQuote(abs)}`,\n    );\n    if (result.exitCode === EXIT_NOT_FOUND) throw new FileNotFoundError(path);\n    if (result.exitCode !== 0) {\n      throw new Error(`deleteFile ${path} failed (exit ${result.exitCode}): ${result.stderr.trim()}`);\n    }\n  }\n\n  async copyFile(src: string, dest: string, options?: CopyOptions): Promise<void> {\n    const srcAbs = await this.resolveAsync(src);\n    const destAbs = await this.resolveAsync(dest);\n    await this.assertContainedRealpath(srcAbs, src);\n    await this.assertContainedDest(destAbs, dest);\n    const recursive = options?.recursive ? '-r ' : '';\n    if (options?.overwrite === false) {\n      // Atomic no-clobber: directories claim the destination with an exclusive\n      // mkdir; files copy to a temp name then hardlink into place (link(2)\n      // fails if the destination exists). No racy exists() pre-check.\n      const result = await this.exec(\n        [\n          `src=${shellQuote(srcAbs)}`,\n          `dest=${shellQuote(destAbs)}`,\n          `if [ ! -e \"$src\" ] && [ ! -L \"$src\" ]; then exit ${EXIT_NOT_FOUND}; fi`,","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/agents/sandbox-filesystem.ts#L297-L333","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — may delete a directory and fail\nawait sandbox.fs.deleteFile('/tmp/data');\n\n// after — check kind first or use recursive removal API\nconst stat = await sandbox.fs.stat('/tmp/data');\nif (stat.isDirectory) {\n  await sandbox.fs.rmdir('/tmp/data', { recursive: true });\n} else {\n  await sandbox.fs.deleteFile('/tmp/data');\n}","handlingStrategy":"try-catch","validationCode":"// check kind and writability before deleting\nconst stat = await sandbox.fs.stat(path); // throws FileNotFoundError if missing\nif (stat.isDirectory) {\n  throw new Error(`${path} is a directory; use the directory removal API`);\n}","typeGuard":"function isFileNotFoundError(e: unknown): e is FileNotFoundError {\n  return e instanceof FileNotFoundError;\n}","tryCatchPattern":"try {\n  await sandbox.fs.deleteFile(path);\n} catch (e) {\n  if (isFileNotFoundError(e)) return; // already gone\n  console.error(`deleteFile failed: ${(e as Error).message}`);\n  throw e;\n}","preventionTips":["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."],"tags":["sandbox","filesystem","shell-command","delete"],"backgroundTag":"sandbox-command-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}