can1357/oh-my-pi · error · Error
Path is not a file: ${pathArg}
Error message
Path is not a file: ${pathArg} What it means
The delete tool only removes regular files. If stat succeeds but the entry is a directory, symlink-to-directory, socket, FIFO, or device, the operation refuses with this message rather than recursing or unlinking something unexpected.
Source
Thrown at packages/coding-agent/src/cursor.ts:355
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);
}
function decodeToolCallId(toolCallId?: string): string {View on GitHub (pinned to 9690622007)
Solutions
- If you intend to remove a directory, use the bash/shell tool with `rm -r <dir>` instead of the file-delete tool.
- Point pathArg at an individual regular file inside the directory.
- Check what the path is with `ls -la <path>` / `stat <path>` before deleting.
Example fix
// before
await execDelete("dist"); // dist is a directory
// after (shell tool)
await bash("rm -r dist"); Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from "node:fs";
const s = statSync(absolutePath, { throwIfNoEntry: false });
if (s && !s.isFile()) throw new Error(`${absolutePath} is not a regular file; use rm -r for directories`);
Type guard
function isFileStat(s: import("node:fs").Stats | undefined): s is import("node:fs").Stats & { isFile(): true } {
return !!s && s.isFile();
} Try / catch
try {
await execDelete(pathArg);
} catch (e) {
if (String(e.message).startsWith("Path is not a file")) {
// route directories to `rm -r` via the shell tool instead
} else throw e;
} Prevention
- Check the entry type with stat before deleting.
- Use the shell tool (`rm -r`) for directories; reserve the delete tool for files.
- Don't assume a path's type from its name or extension.
When it happens
Trigger: pathArg resolves to an existing directory (most common), a special file, or a symlink pointing at a directory, in the executeDelete path.
Common situations: Asking the agent to 'delete the build folder' through the file-delete tool instead of a shell command; passing a directory that was expected to be a file after a refactor.
Related errors
- Managed skill "${name}" SKILL.md is not a regular file; refu
- Shared-folder destination escapes its configured root
- File not found: ${pathArg}
- local:// URL must resolve to a file or directory: ${url.href
- File not found: ${filePath}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6afb37db07633afb.
Report an issue: GitHub.