mastra-ai/mastra · error · HTTPException
Failed to resolve created skill
Error message
Failed to resolve created skill
What it means
This 500 is thrown when a skill was just created but the immediate `skillStore.getByIdResolved(id)` read-back returns null, meaning the server cannot assemble the resolved skill (thin record + version config) to return. The write succeeded enough not to throw, but the follow-up read found nothing. This indicates an internal consistency/storage anomaly right after create.
Source
Thrown at packages/server/src/server/handlers/stored-skills.ts:372
visibility,
name,
description,
instructions,
license,
compatibility,
source,
references: indexedPaths.references ?? references,
scripts: indexedPaths.scripts ?? scripts,
assets: indexedPaths.assets ?? assets,
files,
metadata: scopeStoredResourceMetadata(metadata, await getStoredResourceScope(mastra, requestContext)),
},
});
// Return the resolved skill (thin record + version config)
const resolved = await skillStore.getByIdResolved(id);
if (!resolved) {
throw new HTTPException(500, { message: 'Failed to resolve created skill' });
}
return enrichOrStripFavorites(mastra, requestContext, 'skill', resolved);
} catch (error) {
return handleError(error, 'Error creating stored skill');
}
},
});
/**
* PATCH /stored/skills/:storedSkillId - Update a stored skill
*/
export const UPDATE_STORED_SKILL_ROUTE = createRoute({
method: 'PATCH',
path: '/stored/skills/:storedSkillId',
responseType: 'json',
pathParamSchema: storedSkillIdPathParams,
bodySchema: updateStoredSkillBodySchema,View on GitHub (pinned to 75dd419e61)
Solutions
- Retry the GET /api/stored-skills/:id request — the record may be readable a moment later
- Use a storage adapter with strong read-after-write consistency (single primary, no stale replicas)
- Check the adapter's `getByIdResolved` implementation for bugs resolving version config
- Enable storage logging to confirm the create actually persisted the record and its version rows
Example fix
// before
const skill = await createSkill(...).then(r => r.json());
// after
const res = await createSkill(...);
if (res.status === 500) {
await new Promise(r => setTimeout(r, 250));
const skill = await fetch(`/api/stored-skills/${id}`).then(r => r.json());
} Defensive patterns
Strategy: retry
Validate before calling
null
Type guard
null
Try / catch
try {
const created = await createStoredSkill(body);
return created;
} catch (e) {
if (String((e as Error).message).includes('Failed to resolve created skill')) {
await new Promise(r => setTimeout(r, 250));
return fetch(`/api/stored-skills/${id}`).then(r => r.json()); // read-back retry
}
throw e;
} Prevention
- Use storage with strong read-after-write consistency
- Avoid custom getByIdResolved implementations unless well tested
- Avoid concurrent create/delete of the same skill ID
- Retry the read (not the create) on this error to avoid duplicates
When it happens
Trigger: Storage adapter with read-after-write inconsistency (e.g. replication lag or caching layer); the create wrote a record that `getByIdResolved` cannot resolve because version config rows were not committed; concurrent delete of the same ID between create and read-back.
Common situations: Custom/experimental storage adapters; distributed Postgres with read replicas serving the immediate read; a bug in a custom `getByIdResolved` implementation; concurrent workers deleting duplicate skills.
Related errors
- Failed to resolve created agent
- Failed to resolve updated agent
- Failed to resolve created MCP client
- Failed to resolve updated skill
- AcpAgent does not support resuming suspended generate calls
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/5460af538b2b58d0.
Report an issue: GitHub.