{"record":{"id":"e73fc8adc4d1bf7e","repo":"mastra-ai/mastra","slug":"blob-storage-domain-is-not-available","errorCode":null,"errorMessage":"Blob storage domain is not available","messagePattern":"Blob storage domain is not available","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"packages/server/src/server/handlers/stored-skills.ts","lineNumber":590,"sourceCode":"    'Snapshots the skill directory from the filesystem into content-addressable blob storage, creates a new version with a tree manifest, and marks the skill as published',\n  tags: ['Stored Skills'],\n  requiresAuth: true,\n  handler: async ({ mastra, requestContext, storedSkillId, skillPath }) => {\n    try {\n      const storage = mastra.getStorage();\n\n      if (!storage) {\n        throw new HTTPException(500, { message: 'Storage is not configured' });\n      }\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\n      const blobStore = await storage.getStore('blobs');\n      if (!blobStore) {\n        throw new HTTPException(500, { message: 'Blob storage domain is not available' });\n      }\n\n      // Verify skill exists. Skill metadata lives on the resolved snapshot.\n      const existing = await skillStore.getByIdResolved(storedSkillId);\n      if (!existing) {\n        throw new HTTPException(404, { message: `Stored skill with id ${storedSkillId} not found` });\n      }\n      assertStoredResourceScope(existing, await getStoredResourceScope(mastra, requestContext));\n\n      // Throws 404 if the caller isn't the owner, admin, or `stored-skills:write[:<id>]` holder.\n      assertWriteAccess({\n        requestContext,\n        resource: 'stored-skills',\n        resourceId: storedSkillId,\n        action: 'edit',\n        record: existing,\n      });\n","sourceCodeStart":572,"sourceCodeEnd":608,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/stored-skills.ts#L572-L608","documentation":"Thrown when `storage.getStore('blobs')` returns null — storage exists and the skills store resolved, but the blob storage domain is unavailable. Publishing skill files requires the blob store, so the handler aborts with a 500.","triggerScenarios":"Publish-skill request with an adapter that has skills support but no `blobs` domain (older adapter, partial custom adapter, blob domain disabled).","commonSituations":"Adapter versions where blob storage was added later than skills; custom adapters that store metadata but not blobs; configuration that explicitly disables blob storage.","solutions":["Upgrade the storage adapter so both `skills` and `blobs` domains are available","Use an official adapter version known to support blob storage","Add the `blobs` domain to a custom adapter","Log `await storage.getStore('blobs')` at startup to verify domain availability before serving traffic"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const [skills, blobs] = await Promise.all([storage.getStore('skills'), storage.getStore('blobs')]);\nif (!skills || !blobs) throw new Error('Storage adapter must support both skills and blobs domains');","typeGuard":null,"tryCatchPattern":"try { await publishStoredSkill(req); } catch (e) {\n  if (e.status === 500 && /Blob storage domain/.test(e.message)) throw new Error('Upgrade adapter to one with blob storage support');\n  throw e;\n}","preventionTips":["Verify blob support when choosing a storage adapter","Upgrade adapters as a unit so skills and blobs domains arrive together","Add a startup check for all required storage domains","Avoid custom adapters that omit the blobs domain"],"tags":["storage","blobs","adapter"],"backgroundTag":"storage-domain-unavailable","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}