mastra-ai/mastra · critical
Blob not found for hash ${entry.blobHash} (file: ${path})
Error message
Blob not found for hash ${entry.blobHash} (file: ${path}) What it means
After finding a valid tree entry, VersionedSkillSource.readFile fetches content from the BlobStore by the entry's blobHash; if the blob store returns nothing, the manifest references content that is missing from storage. This indicates storage-level corruption or incomplete retention: the version tree metadata survived but its blob did not.
Source
Thrown at packages/core/src/workspace/skills/versioned-skill-source.ts:116
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);
if (!this.#directories.has(normalized)) {
throw new Error(`Directory not found in skill version tree: ${path}`);
}
const prefix = normalized === '' ? '' : normalized + '/';View on GitHub (pinned to 75dd419e61)
Solutions
- Republish the skill version so blobs are rewritten and the tree matches stored content.
- Verify the BlobStore instance is connected to the same storage that holds the published blobs (same DB/prefix).
- Check blob retention/GC policies so blobs for live versions aren't deleted.
- Restore missing blobs from backup, or delete the broken version and re-publish.
Example fix
// before const src = new VersionedSkillSource(tree, devBlobStore, createdAt); // blobs live in prod store // after const src = new VersionedSkillSource(tree, prodBlobStore, createdAt);
Defensive patterns
Strategy: try-catch
Try / catch
try {
return await versioned.readFile(path);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Blob not found for hash')) {
logger.error({ path }, 'Skill blob missing from store; version is corrupt — republish required');
throw new SkillCorruptError(path, { cause: err });
}
throw err;
} Prevention
- Never run blob GC/retention on blobs referenced by live skill versions.
- Publish atomically: write all blobs before committing the version tree.
- Point the source at the same storage backend used at publish time.
- Monitor for orphaned trees via a periodic tree-vs-blob integrity check.
When it happens
Trigger: Calling readFile on a file whose blobHash is not present in the configured BlobStore — blob was deleted by retention/GC, storage backend was swapped or reset, partial publish wrote the tree without all blobs, or reading with a BlobStore instance pointed at a different database/prefix.
Common situations: Environments pruning old blobs while old skill versions remain listed; restoring storage from a partial backup; switching between dev/prod storage DBs; concurrent publish bugs leaving trees without blobs.
Related errors
- Version-control installation not found.
- Bound Factory work item not found.
- The related work item chain contains a cycle.
- Notification ${current.id} is missing agentId
- Notification ${current.id} is missing resourceId
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/274ab5d0e8b715d1.
Report an issue: GitHub.