mastra-ai/mastra · error

Failed to load models (${res.status})

Error message

Failed to load models (${res.status})

What it means

The `useAvailableModels` hook fetches `/web/config/models` and throws this error for any non-OK HTTP status. The status code is embedded in the message so the developer can distinguish auth problems (401/403) from server failures (500).

Source

Thrown at mastracode/factory-ui/src/hooks/useAvailableModels.ts:28

  modelName: string;
  hasApiKey: boolean;
}

/**
 * Session-independent model catalog for settings pickers (Factory default
 * model, pack editors, OM models). Server-filtered to providers with a
 * credential, so pickers never offer models that cannot run.
 */
export function useAvailableModelsQuery() {
  const { baseUrl } = useApiConfig();
  return useQuery({
    queryKey: queryKeys.availableModels(),
    queryFn: async () => {
      const res = await fetch(`${baseUrl}/web/config/models`, {
        credentials: 'include',
        headers: { Accept: 'application/json' },
      });
      if (!res.ok) throw new Error(`Failed to load models (${res.status})`);
      const data = (await res.json()) as { models: AvailableModelOption[] };
      return data.models;
    },
  });
}

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Check the status in the message: 401/403 → re-authenticate / fix cookie credentials; 500 → check server config for models
  2. Hit `${baseUrl}/web/config/models` directly (curl with cookie) to confirm the server response
  3. Verify `baseUrl` in useApiConfig points at the correct Factory server
  4. Restart/redeploy the server if the models config failed to load

Example fix

// caller-side
const { data: models, isError, error } = useAvailableModels();
if (isError) {
  console.error(error.message); // "Failed to load models (401)"
  if (error.message.includes('401')) await reauthenticate();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight
const probe = await fetch(`${baseUrl}/web/config/models`, { credentials: 'include', headers: { Accept: 'application/json' } });
if (!probe.ok) throw new Error(`Models endpoint unhealthy (${probe.status})`);

Try / catch

try {
  const models = await queryFn();
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Failed to load models')) {
    const status = e.message.match(/\((\d+)\)/)?.[1];
    if (status === '401' || status === '403') await reauthenticate();
    else if (status?.startsWith('5')) showServerErrorBanner();
  } else throw e;
}

Prevention

When it happens

Trigger: `fetch(`${baseUrl}/web/config/models`)` with `credentials: 'include'` resolves with `res.ok === false` — any 4xx/5xx from the config endpoint.

Common situations: Not authenticated (session cookie missing/expired → 401); server misconfiguration or config file missing (500); baseUrl pointing at wrong port/host; reverse proxy blocking the route; UI/server version mismatch after an upgrade.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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