mastra-ai/mastra · error
FilesystemSkillsStorage: skill with id ${id} not found
Error message
FilesystemSkillsStorage: skill with id ${id} not found What it means
FilesystemSkillsStorage.update first loads the skill by id and throws when no skill file matching that id exists on disk. Update is not upsert: you can only update skills that were previously created in the filesystem storage directory.
Source
Thrown at packages/core/src/storage/domains/skills/filesystem.ts:76
const versionId = crypto.randomUUID();
await this.createVersion({
id: versionId,
skillId: skill.id,
versionNumber: 1,
...snapshotConfig,
changedFields: Object.keys(snapshotConfig),
changeMessage: 'Initial version',
});
return structuredClone(entity);
}
async update(input: StorageUpdateSkillInput): Promise<StorageSkillType> {
const { id, ...updates } = input;
const existing = await this.helpers.getById(id);
if (!existing) {
throw new Error(`FilesystemSkillsStorage: skill with id ${id} not found`);
}
const { authorId, visibility, activeVersionId, status, ...rawConfigFields } = updates;
// Filter out undefined keys: callers may spread partial snapshots into
// update() and rely on "omit = no change" semantics. Without this, an
// undefined value would clobber the latest version's populated field
// when spread into newConfig below.
const configFields: Record<string, unknown> = {};
for (const [key, value] of Object.entries(rawConfigFields)) {
if (value !== undefined) configFields[key] = value;
}
// Config field names from StorageSkillSnapshotType
const configFieldNames = [
'name',
'description',
'instructions',View on GitHub (pinned to 75dd419e61)
Solutions
- Create the skill first (or use an upsert pattern: check getById, then create if missing).
- Verify the id is correct and exists via getById/getList before updating.
- Confirm the filesystem storage is configured with the correct base directory / env vars so the skill file is visible.
- Restore the missing skill file or re-seed skills in the target directory.
Example fix
// before
await storage.update({ id: 'my-skill', status: 'active' }); // throws if missing
// after
const existing = await storage.getById('my-skill');
if (!existing) {
await storage.create({ skill: { id: 'my-skill', ...defaults } });
}
await storage.update({ id: 'my-skill', status: 'active' }); Defensive patterns
Strategy: validation
Validate before calling
const existing = await storage.getById(id);
if (!existing) throw new Error(`skill ${id} does not exist; create it first`); Type guard
async function skillExists(storage: FilesystemSkillsStorage, id: string): Promise<boolean> {
return (await storage.getById(id)) != null;
} Try / catch
try {
return await storage.update(input);
} catch (e) {
if (e instanceof Error && e.message.includes('not found')) {
return storage.create({ skill: { ...input, ...defaults } as StorageCreateSkillInput });
}
throw e;
} Prevention
- Implement updates as upsert (check getById first).
- Verify storage base-directory configuration so the skill files resolve.
- Keep ids in sync across environments; don't hardcode ids from other datasets.
- Re-seed or restore skill files after external directory modifications.
When it happens
Trigger: Calling update({ id, ... }) for an id that was never created, was deleted, or whose backing file is missing/renamed on disk; a typo'd or stale id from another environment.
Common situations: Pointing storage at a different base directory than where skills were created (env misconfiguration); id mismatch after a rename or re-seed; calling update before create in a setup script.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- ENOENT: no such file or directory: ${path}
- No versions found for skill ${id}
- Skill with id ${id} not found
- ${this.name}: entity with id ${id} not found
- File not found in composite skill source: ${path}
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/58fe2b32ee507c17.
Report an issue: GitHub.