mastra-ai/mastra · critical · HTTPException

Skills storage domain is not available

Error message

Skills storage domain is not available

What it means

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.

Source

Thrown at packages/server/src/server/handlers/stored-skill-favorites.ts:21

import { storedSkillIdPathParams } from '../schemas/stored-skills';
import { createRoute } from '../server-adapter/routes/route-builder';
import { assertStoredResourceScope, getStoredResourceScope } from '../utils';

import { assertReadAccess, getCallerAuthorId } from './authorship';
import { requireBuilderFeature } from './editor-builder';
import { handleError } from './error';

/**
 * Resolves the storage and favorites domains, throwing 500 if unavailable.
 */
async function getFavoritesContext(mastra: Parameters<typeof requireBuilderFeature>[0]) {
  const storage = mastra.getStorage();
  if (!storage) {
    throw new HTTPException(500, { message: 'Storage is not configured' });
  }
  const skillStore = await storage.getStore('skills');
  if (!skillStore) {
    throw new HTTPException(500, { message: 'Skills storage domain is not available' });
  }
  const favoritesStore = await storage.getStore('favorites');
  if (!favoritesStore) {
    throw new HTTPException(500, { message: 'Favorites storage domain is not available' });
  }
  return { skillStore, favoritesStore };
}

/**
 * PUT /stored/skills/:storedSkillId/favorite
 */
export const FAVORITE_STORED_SKILL_ROUTE = createRoute({
  method: 'PUT',
  path: '/stored/skills/:storedSkillId/favorite',
  responseType: 'json',
  pathParamSchema: storedSkillIdPathParams,
  responseSchema: favoriteToggleResponseSchema,
  summary: 'Favorite a stored skill',

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Use/upgrade to an official storage adapter version that implements the 'skills' domain, aligned with your @mastra/core and server versions.
  2. If running a custom storage class, add the skills domain to its getStore implementation.
  3. Sanity-check at boot: `await mastra.getStorage()?.getStore('skills')` and fail fast with a clear message if undefined.
  4. Pin all @mastra/* storage-related packages to the same release line to avoid domain-support mismatches.

Example fix

// before
const storage = new MyLegacyAdapter(); // no skills domain
// after
pnpm add @mastra/pg@latest
const storage = new MastraPg({ connectionString: process.env.DATABASE_URL });
Defensive patterns

Strategy: validation

Validate before calling

const storage = mastra.getStorage();
if (!storage) throw new Error('No storage configured');
const skillStore = await storage.getStore('skills');
if (!skillStore) throw new Error('Storage adapter lacks the skills domain — upgrade or replace the adapter');
const favoritesStore = await storage.getStore('favorites');
if (!favoritesStore) throw new Error('Storage adapter lacks the favorites domain');

Type guard

async function supportsDomains(storage: { getStore(name: string): Promise<unknown> }, domains: string[]): Promise<string[]> {
  const missing: string[] = [];
  for (const d of domains) if (!(await storage.getStore(d))) missing.push(d);
  return missing;
}

Try / catch

try {
  const res = await fetch(`/api/stored/skills/${id}/favorite`, { method: 'PUT' });
  if (res.status === 500) {
    const body = await res.json().catch(() => ({}));
    if (body?.message?.includes('storage domain is not available')) {
      throw new Error(`Adapter missing domain: ${body.message}`);
    }
  }
} catch (err) {
  console.error(err);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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