mastra-ai/mastra · error
models.dev returned ${response.status}
Error message
models.dev returned ${response.status} What it means
fetchBedrockModels queries the models.dev API to enumerate available Amazon Bedrock models. When the HTTP response status is not ok (4xx/5xx), the function throws this generic error embedding the numeric status. It is a fail-fast guard against parsing garbage from a failed catalog request.
Source
Thrown at mastracode/sdk/src/providers/amazon-bedrock.ts:52
interface CatalogCacheEntry {
fetchedAt: number;
ttl: number;
models: BedrockModelEntry[];
}
let catalogCache: CatalogCacheEntry | null = null;
let inflightFetch: Promise<BedrockModelEntry[]> | null = null;
/** Reset the in-process Bedrock catalog cache (test seam). */
export function clearBedrockCatalogCache(): void {
catalogCache = null;
inflightFetch = null;
}
async function fetchBedrockModels(signal: AbortSignal): Promise<BedrockModelEntry[]> {
const response = await fetch(MODELS_DEV_API_URL, { signal });
if (!response.ok) {
throw new Error(`models.dev returned ${response.status}`);
}
const data = (await response.json()) as Record<string, { models?: Record<string, unknown> }>;
const provider = data[BEDROCK_PROVIDER_ID];
const models = provider?.models ?? {};
return Object.keys(models)
.sort()
.map(id => ({ id }));
}
/**
* Return the available Amazon Bedrock models.
*
* - Returns the cached list when a recent fetch succeeded.
* - On cache miss / expiry, fetches the models.dev catalog with a 5s timeout and
* caches it for an hour.
* - On fetch failure, returns a small hard-coded fallback (so packs still work
* offline) and caches that briefly to avoid hammering the network.
*View on GitHub (pinned to 75dd419e61)
Solutions
- Check network connectivity and retry, since 5xx/429 are usually transient
- Inspect the status code in the message: 403/401 means a proxy or firewall is intercepting the request
- Verify MODELS_DEV_API_URL is reachable (curl it directly) and the API has not moved
- Pin a fallback/offline model list or cache the last successful response for offline use
Example fix
// before
const models = await sdk.models();
// after
let models;
try {
models = await sdk.models();
} catch (err) {
if ((err as Error).message.startsWith('models.dev returned')) {
models = FALLBACK_BEDROCK_MODELS; // cached/known list
} else throw err;
} Defensive patterns
Strategy: fallback
Validate before calling
const res = await fetch(MODELS_DEV_API_URL);
if (!res.ok) throw new Error(`models.dev unreachable: ${res.status}`); Type guard
null
Try / catch
try {
models = await sdk.models();
} catch (err) {
if (err instanceof Error && /models\.dev returned \d+/.test(err.message)) {
models = CACHED_MODELS; // or rethrow with context
} else throw err;
} Prevention
- Cache the last successful models.dev response for offline/failure fallback
- Check the status code embedded in the message to distinguish transient (5xx/429) from permanent (404) failures
- Add a timeout via AbortSignal so a hung request fails fast
- Alert on repeated models.dev failures in production
When it happens
Trigger: Calling `models` (which calls fetchBedrockModels) when the models.dev endpoint returns a non-2xx status: 404 (API path changed), 429 (rate limited), 5xx (service outage), or a proxy/firewall blocking the request.
Common situations: Corporate proxies or firewalls returning 403/502 for external APIs; models.dev being temporarily down or rate-limiting; offline or air-gapped environments where a captive portal returns an HTML error page with 4xx/5xx; DNS hijacking to an error page.
Related errors
- Slack OAuth HTTP error: ${tokenResponse.status} ${tokenRespo
- Failed to stream background tasks: ${response.statusText}
- Failed to stream agent builder action: ${response.statusText
- Failed to observe agent builder action stream: ${response.st
- Failed to observe agent builder action stream legacy: ${resp
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/d2aeea3a55663d30.
Report an issue: GitHub.