{"record":{"id":"42dcdcb03119b6e9","repo":"mastra-ai/mastra","slug":"skills-storage-domain-is-not-available-42dcdc","errorCode":null,"errorMessage":"Skills storage domain is not available","messagePattern":"Skills storage domain is not available","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"critical","filePath":"packages/server/src/server/handlers/stored-skill-favorites.ts","lineNumber":21,"sourceCode":"import { storedSkillIdPathParams } from '../schemas/stored-skills';\nimport { createRoute } from '../server-adapter/routes/route-builder';\nimport { assertStoredResourceScope, getStoredResourceScope } from '../utils';\n\nimport { assertReadAccess, getCallerAuthorId } from './authorship';\nimport { requireBuilderFeature } from './editor-builder';\nimport { handleError } from './error';\n\n/**\n * Resolves the storage and favorites domains, throwing 500 if unavailable.\n */\nasync function getFavoritesContext(mastra: Parameters<typeof requireBuilderFeature>[0]) {\n  const storage = mastra.getStorage();\n  if (!storage) {\n    throw new HTTPException(500, { message: 'Storage is not configured' });\n  }\n  const skillStore = await storage.getStore('skills');\n  if (!skillStore) {\n    throw new HTTPException(500, { message: 'Skills storage domain is not available' });\n  }\n  const favoritesStore = await storage.getStore('favorites');\n  if (!favoritesStore) {\n    throw new HTTPException(500, { message: 'Favorites storage domain is not available' });\n  }\n  return { skillStore, favoritesStore };\n}\n\n/**\n * PUT /stored/skills/:storedSkillId/favorite\n */\nexport const FAVORITE_STORED_SKILL_ROUTE = createRoute({\n  method: 'PUT',\n  path: '/stored/skills/:storedSkillId/favorite',\n  responseType: 'json',\n  pathParamSchema: storedSkillIdPathParams,\n  responseSchema: favoriteToggleResponseSchema,\n  summary: 'Favorite a stored skill',","sourceCodeStart":3,"sourceCodeEnd":39,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/stored-skill-favorites.ts#L3-L39","documentation":"Thrown by getFavoritesContext when storage is configured but `storage.getStore('skills')` returns no store — the storage backend does not provide the 'skills' domain. The favorites routes need the skills store to resolve the skill (getByIdResolved) before recording a favorite, so the request fails with HTTP 500.","triggerScenarios":"PUT/DELETE /api/stored/skills/:storedSkillId/favorite where the configured storage adapter returns undefined for `getStore('skills')` — adapter doesn't implement the skills domain or is version-mismatched with the server.","commonSituations":"Custom or third-party storage adapter missing the skills domain; older adapter version that predates stored-skills support while the server package was upgraded; storage backend that implements only a subset of domains; typo'd/incorrect domain wiring in a custom getStore implementation.","solutions":["Use/upgrade to an official storage adapter version that implements the 'skills' domain, aligned with your @mastra/core and server versions.","If running a custom storage class, add the skills domain to its getStore implementation.","Sanity-check at boot: `await mastra.getStorage()?.getStore('skills')` and fail fast with a clear message if undefined.","Pin all @mastra/* storage-related packages to the same release line to avoid domain-support mismatches."],"exampleFix":"// before\nconst storage = new MyLegacyAdapter(); // no skills domain\n// after\npnpm add @mastra/pg@latest\nconst storage = new MastraPg({ connectionString: process.env.DATABASE_URL });","handlingStrategy":"validation","validationCode":"const storage = mastra.getStorage();\nif (!storage) throw new Error('No storage configured');\nconst skillStore = await storage.getStore('skills');\nif (!skillStore) throw new Error('Storage adapter lacks the skills domain — upgrade or replace the adapter');\nconst favoritesStore = await storage.getStore('favorites');\nif (!favoritesStore) throw new Error('Storage adapter lacks the favorites domain');","typeGuard":"async function supportsDomains(storage: { getStore(name: string): Promise<unknown> }, domains: string[]): Promise<string[]> {\n  const missing: string[] = [];\n  for (const d of domains) if (!(await storage.getStore(d))) missing.push(d);\n  return missing;\n}","tryCatchPattern":"try {\n  const res = await fetch(`/api/stored/skills/${id}/favorite`, { method: 'PUT' });\n  if (res.status === 500) {\n    const body = await res.json().catch(() => ({}));\n    if (body?.message?.includes('storage domain is not available')) {\n      throw new Error(`Adapter missing domain: ${body.message}`);\n    }\n  }\n} catch (err) {\n  console.error(err);\n}","preventionTips":["Run a domain-support probe (getStore for 'skills' and 'favorites') at server startup and log gaps.","Keep storage adapters on the same version line as @mastra/core and @mastra/server.","If implementing custom storage, cover every domain your enabled features need.","Document required domains per feature so ops knows what the adapter must support."],"tags":["storage","storage-domain","http-500","skills","adapter"],"backgroundTag":"storage-domain-unavailable","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}