mastra-ai/mastra · error
File not found in skill version tree
Error message
File not found in skill version tree: ${path} What it means
VersionedSkillSource.readFile requires the normalized path to be a key in the version tree's entries map; if it isn't, the file is not part of this published skill version and the error is thrown. Unlike stat, directories cannot be read, so directory paths also fail here.
Solutions
- Check the exact path exists via exists(path) or by inspecting the version tree entries.
- Ensure paths are relative to the skill root with no leading slash or skill-directory prefix.
- Point the source at the correct skill version tree that contains the file.
- Republish the skill so the desired file is included in the version.
Example fix
// before
await versioned.readFile('/references/api.md'); // leading slash + maybe absent
// after
await versioned.readFile('references/api.md'); Defensive patterns
Strategy: validation
Validate before calling
if (!(await versioned.exists(path))) {
return null;
}
const content = await versioned.readFile(path); Try / catch
try {
return await versioned.readFile(path);
} catch (err) {
if (err instanceof Error && err.message.startsWith('File not found in skill version tree')) {
return fallbackContent(path); // e.g. prompt the agent the file is unavailable
}
throw err;
} Prevention
- Derive file paths from the version tree entries, not the live filesystem.
- Match exact casing; lookups are key-based on tree entries.
- Republish versions after adding new files agents depend on.
When it happens
Trigger: Calling readFile with a path not present in SkillVersionTree.entries — file never published, exists only in another version, path includes an extra skill-dir prefix, or casing/whitespace mismatch.
Common situations: Reading 'references/api.md' that was added after this version was published; agents accessing files listed in a newer SKILL.md while pinned to an older version; case-sensitive lookups failing on 'Readme.md' vs 'readme.md'.
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
- Directory not found in skill version tree
- Path not found in skill version tree
- Directory not found in composite skill source
- ENOENT: no such file or directory
- File not found in composite skill source
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/bdb0033569055774.
Report an issue: GitHub.
Appendix: source
Thrown at packages/core/src/workspace/skills/versioned-skill-source.ts:111
if (this.#directories.has(normalized)) {
return {
name,
type: 'directory',
size: 0,
createdAt: this.#versionCreatedAt,
modifiedAt: this.#versionCreatedAt,
};
}
throw new Error(`Path not found in skill version tree: ${path}`);
}
async readFile(path: string): Promise<string | Buffer> {
const normalized = this.#normalizePath(path);
const entry = this.#tree.entries[normalized];
if (!entry) {
throw new Error(`File not found in skill version tree: ${path}`);
}
const blob = await this.#blobStore.get(entry.blobHash);
if (!blob) {
throw new Error(`Blob not found for hash ${entry.blobHash} (file: ${path})`);
}
// Decode base64-encoded binary content back to Buffer
if (entry.encoding === 'base64') {
return Buffer.from(blob.content, 'base64');
}
return blob.content;
}
async readdir(path: string): Promise<SkillSourceEntry[]> {
const normalized = this.#normalizePath(path);
View on GitHub (pinned to 75dd419e61)