can1357/oh-my-pi · error
File not found: ${targetPath}
Error message
File not found: ${targetPath} What it means
After computing the target path (either the skill's SKILL.md file, the skill's baseDir for path-only resolution, or a contained resolved path), the handler calls `fs.stat(targetPath)`. If stat fails with ENOENT the target does not exist, and the handler converts the raw ENOENT into this clearer 'File not found' error. Any other stat error (permissions, I/O) is rethrown unchanged.
Source
Thrown at packages/coding-agent/src/internal-urls/skill-protocol.ts:102
const contained = await resolveContainedPath(skill.containRoot, resolvedPath);
if (contained.status === "outside") {
throw new Error(`skill:// path resolves outside the plugin root: ${url.href}`);
}
if (contained.status === "missing") {
throw new Error(`File not found: ${resolvedPath}`);
}
targetPath = contained.realPath;
}
} else {
targetPath = context?.pathOnly === true ? skill.baseDir : skill.filePath;
}
let stats: fsTypes.Stats;
try {
stats = await fs.stat(targetPath);
} catch (error) {
if (isEnoent(error)) {
throw new Error(`File not found: ${targetPath}`);
}
throw error;
}
if (stats.isDirectory()) {
return buildDirectoryResource(url.href, targetPath);
}
if (!stats.isFile()) {
throw new Error(`skill:// URL must resolve to a file or directory: ${url.href}`);
}
const content = await Bun.file(targetPath).text();
return {
url: url.href,
content,
contentType: getContentType(targetPath),
size: Buffer.byteLength(content, "utf-8"),
sourcePath: targetPath,View on GitHub (pinned to 9690622007)
Solutions
- Stat the path from the error message directly on disk to confirm it is missing.
- Re-install or re-sync the skill so its SKILL.md/baseDir exists (remove stale skill cache entries).
- Fix the path in the skill:// URL — check spelling and the skill's actual directory layout.
- If you control skill registration, ensure `filePath`/`baseDir` point at real paths at registration time.
Example fix
// before
const res = await handler.resolve(parseInternalUrl("skill://old-skill")); // SKILL.md deleted
// after
const res = await handler.resolve(parseInternalUrl("skill://new-skill")); // resynced skill Defensive patterns
Strategy: try-catch
Validate before calling
import * as fs from "node:fs/promises";
try {
await fs.stat(targetPath); // SKILL.md, baseDir, or joined path
} catch {
throw new Error(`skill target missing on disk: ${targetPath}`);
} Try / catch
try {
const resource = await handler.resolve(url);
} catch (err) {
if (err instanceof Error && err.message.startsWith("File not found:")) {
// resync skills, then retry once
await resyncSkills();
return handler.resolve(url);
}
throw err;
} Prevention
- Keep the skills directory in sync; clear stale caches pointing at deleted paths.
- Verify the skill's filePath/baseDir exists at registration time.
- Validate the path portion of skill:// URLs against the skill directory listing.
- Distinguish plugin skills (containRoot) from plain skills — their lookup paths differ.
When it happens
Trigger: `SkillProtocolHandler.resolve()` where: (a) a `skill://<name>` URL is used and the skill's `filePath` (its SKILL.md) does not exist on disk; (b) a `skill://<name>/<path>` URL is used without a `containRoot` and `path.join(skill.baseDir, relativePath)` does not exist; (c) `context.pathOnly === true` and the skill's `baseDir` directory was deleted.
Common situations: Skill discovered from a config/marketplace but its SKILL.md was never written or was deleted; skills loaded from a stale cache pointing at removed directories; mistyped paths in skill:// URLs for non-plugin skills; a partially-synced skills directory.
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
- File not found: ${path}
- Local file not found: ${url.href}
- File not found: ${resolvedPath}
- cannot stat {file}: {error}
- File not found: ${relativePath}
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/dd24700ed492d7f2.
Report an issue: GitHub.