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

  1. Republish the skill version so blobs are rewritten and the tree matches stored content.
  2. Verify the BlobStore instance is connected to the same storage that holds the published blobs (same DB/prefix).
  3. Check blob retention/GC policies so blobs for live versions aren't deleted.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/274ab5d0e8b715d1. Report an issue: GitHub.