can1357/oh-my-pi · error · Error
File not found: ${pathArg}
Error message
File not found: ${pathArg} What it means
The delete tool path checks that the requested path exists via fs.statSync before removing it; any stat failure (ENOENT, permissions causing traversal failure, dangling symlink) is reported uniformly as 'File not found'. It fails before any rm occurs, so nothing is deleted.
Source
Thrown at packages/coding-agent/src/cursor.ts:352
// different question from "does the user's policy allow this call" — without
// this, a configured `deny` or an `always-ask` session still lost the file.
const refusal = refuseByWritePolicy(options, toolName, pathArg);
if (refusal) {
return createToolResultMessage(toolCallId, toolName, buildToolErrorResult(refusal), true);
}
options.emitEvent?.({ type: "tool_execution_start", toolCallId, toolName, args: { path: pathArg } });
const absolutePath = resolveToCwd(pathArg, options.getCwd?.() ?? options.cwd);
let isError = false;
let result: AgentToolResult<unknown>;
try {
let fileStat: fs.Stats | undefined;
try {
fileStat = fs.statSync(absolutePath);
} catch {
throw new Error(`File not found: ${pathArg}`);
}
if (!fileStat.isFile()) {
throw new Error(`Path is not a file: ${pathArg}`);
}
fs.rmSync(absolutePath);
const sizeText = fileStat.size ? ` (${fileStat.size} bytes)` : "";
const message = `Deleted ${pathArg}${sizeText}`;
result = { content: [{ type: "text", text: message }], details: {} };
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
result = buildToolErrorResult(message);
isError = true;
}
options.emitEvent?.({ type: "tool_execution_end", toolCallId, toolName, result, isError });
return createToolResultMessage(toolCallId, toolName, result, isError);View on GitHub (pinned to 9690622007)
Solutions
- Verify the file exists: `ls -la <path>` from the same working directory the tool uses.
- Fix the path (typos, correct relative path, correct extension/case).
- If the file is already gone, treat the delete as a no-op and skip the call.
- For broken symlinks, delete the link itself with `rm <link>` directly.
Example fix
// before
await execDelete("./outputs/repot.txt"); // typo
// after
await execDelete("./outputs/report.txt"); Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from "node:fs";
if (!statSync(absolutePath, { throwIfNoEntry: false })) {
throw new Error(`Skipping delete: ${absolutePath} does not exist`);
} Try / catch
try {
await execDelete(pathArg);
} catch (e) {
if (String(e.message).startsWith("File not found")) {
// already gone — treat as idempotent success
} else throw e;
} Prevention
- Stat or `ls` the path before deleting; treat missing file as a no-op.
- Resolve relative paths against the same cwd the tool uses.
- Watch for case-sensitivity mismatches on case-sensitive filesystems.
When it happens
Trigger: Calling the delete operation with a pathArg that does not exist at the resolved absolute path, including typos, wrong working directory, a deleted file, or a broken symlink.
Common situations: Model/agent deleting a temp file that was already cleaned up; relative path resolved against an unexpected cwd; case-sensitive filesystem mismatch (Report.PDF vs report.pdf).
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- cannot stat {0}: No such file or directory
- Path is not a file: ${pathArg}
- package.json not found at ${absolutePath}
- Marketplace catalog not found at ${tried.map(p => `"${p}"`).
- Unpacked ASAR file '${label}' was not found
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/1fd598820acedda3.
Report an issue: GitHub.