can1357/oh-my-pi · error · ToolError
Path '${localReadPath}' not found
Error message
Path '${localReadPath}' not found What it means
After the read path fails initial filesystem resolution, ReadTool tries recovery paths (approved plan recovery, suffix/glob resolution, delimited multi-path reads). If none succeed, it throws a plain 'Path not found' ToolError naming the local path it attempted.
Source
Thrown at packages/coding-agent/src/tools/read.ts:1305
const approvedPlanPath = this.#approvedPlanAlias(absolutePath);
if (approvedPlanPath) {
try {
const approvedPlanStat = await Bun.file(approvedPlanPath).stat();
absolutePath = approvedPlanPath;
fileSize = approvedPlanStat.size;
isDirectory = approvedPlanStat.isDirectory();
recoveredApprovedPlan = true;
} catch {
// The referenced plan disappeared after resolution; continue through
// the ordinary delimited-path fallback and not-found error.
}
}
}
if (!recoveredApprovedPlan && !suffixResolution) {
const delimitedResult = await this.#tryReadDelimitedPaths(readPath, signal);
if (delimitedResult) return delimitedResult;
throw new ToolError(`Path '${localReadPath}' not found`);
}
} else {
throw error;
}
}
if (isDirectory) {
if (isMultiRange(parsed)) {
throw new ToolError("Multi-range line selectors are not supported for directory listings.");
}
const { offset, limit } = selToOffsetLimit(parsed);
// Directory listings are deterministic and fast; never abort them mid-scan
// (an interrupt would otherwise surface a misleading "Operation aborted").
const dirResult = await this.#readDirectory(absolutePath, offset, limit, undefined);
if (suffixResolution) {
dirResult.details ??= {};
dirResult.details.suffixResolution = suffixResolution;
}View on GitHub (pinned to 9690622007)
Solutions
- Verify the path exists (ls the parent directory) and fix the spelling/casing.
- Use the exact path from a previous successful read or directory listing.
- If the file was deleted/renamed, re-locate it via grep or directory read before retrying.
Example fix
// before
read("src/ap.ts")
// after
read("src/app.ts") // path verified via directory listing Defensive patterns
Strategy: try-catch
Validate before calling
if (!fs.existsSync(localReadPath)) { /* locate via glob or directory listing before read */ } Type guard
null
Try / catch
try { return await read(path) } catch (e) { if (e instanceof ToolError && e.message.includes('not found')) { const alt = await glob('**/'+path.basename(path)); if (alt[0]) return await read(alt[0]); } throw e; } Prevention
- Derive paths from directory listings or prior read results, never from memory
- Watch for case-sensitivity on Linux filesystems
- Re-verify paths after any rename/delete operation
When it happens
Trigger: read() on a path that does not exist, with no glob-suffix match and no delimited-path alternative: e.g. read('/repo/src/missing.ts'), a typo'd path, or a file outside the workspace root when no suffix can recover it.
Common situations: Stale references after a rename/delete, case-sensitivity mismatches on Linux, typos in agent-generated paths, or reading a file that was never created.
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
- Path not found: ${absolutePath}
- Path not found: ${scopePath}
- unknown filetype: {ft_debug}
- Is a directory
- Too many levels of symbolic links
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/49059b4df31a7844.
Report an issue: GitHub.