can1357/oh-my-pi · error

models catalog fetch failed: ${response.status}

Error message

models catalog fetch failed: ${response.status}

What it means

fetchCatalogPayload downloads the models.dev catalog (optionally zstd-compressed) with revalidation via HTTP caching. It throws when the server responds with a non-ok status and there is no cached 304 payload to fall back to.

Source

Thrown at packages/catalog/src/provider-models/openai-compat.ts:224

async function fetchCatalogPayload(
	fetchImpl: FetchImpl,
	session: CatalogSession,
	signal?: AbortSignal,
): Promise<unknown> {
	const headers: Record<string, string> = {
		Accept: "application/zstd, application/json",
		"User-Agent": CATALOG_USER_AGENT,
	};
	if (session.hasPayload && session.etag) {
		headers["If-None-Match"] = session.etag;
	}
	const response = await fetchImpl(MODELS_DEV_URL, { method: "GET", headers, signal });
	if (response.status === 304 && session.hasPayload) {
		return session.payload;
	}
	if (!response.ok) {
		throw new Error(`models catalog fetch failed: ${response.status}`);
	}
	const bytes = new Uint8Array(await response.arrayBuffer());
	const isZstd = bytes.length >= 4 && new DataView(bytes.buffer, bytes.byteOffset).getUint32(0, true) === ZSTD_MAGIC;
	const text = new TextDecoder().decode(isZstd ? await Bun.zstdDecompress(bytes) : bytes);
	const payload: unknown = JSON.parse(text);
	session.payload = payload;
	session.etag = response.headers.get("etag");
	session.hasPayload = true;
	return payload;
}

function mapAnthropicModelsDev(payload: unknown, baseUrl: string): ModelSpec<"anthropic-messages">[] {
	if (!isRecord(payload)) {
		return [];
	}
	const anthropicPayload = payload.anthropic;
	if (!isRecord(anthropicPayload)) {
		return [];

View on GitHub (pinned to 9690622007)

Solutions

  1. Check network/proxy access to https://models.dev and retry
  2. Clear/repopulate the cache so a 304 fallback payload exists
  3. Check for rate limiting (429) and back off
  4. Pin or vendor a catalog payload if you need offline builds
Defensive patterns

Strategy: retry

Try / catch

try {
  payload = await fetchCatalogPayload();
} catch (err) {
  if (err instanceof Error && err.message.startsWith("models catalog fetch failed")) {
    logger.warn("models.dev unreachable; using last cached catalog", { cause: err });
    return cachedPayload;
  }
  throw err;
}

Prevention

When it happens

Trigger: GET MODELS_DEV_URL returns 4xx/5xx (rate limit 429, 5xx outage, blocked by proxy) while session.hasPayload is false (first run or cache cleared).

Common situations: Offline or behind a corporate proxy, models.dev rate-limiting, DNS failures surfaced as odd statuses, transient CDN errors during model discovery.

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 can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/dd12ab8edfca794c. Report an issue: GitHub.