different-ai/openwork · error

Failed to load provider details (${response.status}).

Error message

Failed to load provider details (${response.status}).

What it means

requestLlmProviderCatalogDetail GETs /v1/llm-provider-catalog/:providerId; on a non-ok response it throws with the server message or embedded status. This is the transport-level guard before the payload is schema-checked.

Source

Thrown at ee/apps/den-web/app/(den)/dashboard/_components/llm-provider-data.tsx:484

  const { response, payload } = await requestJson(`/v1/llm-provider-catalog`, { method: "GET" }, 20000);
  if (!response.ok) {
    throw new Error(getErrorMessage(payload, `Failed to load the provider catalog (${response.status}).`));
  }

  return isRecord(payload) && Array.isArray(payload.providers)
    ? payload.providers.map(asCatalogProviderSummary).filter((entry): entry is DenModelsDevProviderSummary => entry !== null)
    : [];
}

export async function requestLlmProviderCatalogDetail(orgId: string, providerId: string) {
  const { response, payload } = await requestJson(
    `/v1/llm-provider-catalog/${encodeURIComponent(providerId)}`,
    { method: "GET" },
    20000,
  );

  if (!response.ok) {
    throw new Error(getErrorMessage(payload, `Failed to load provider details (${response.status}).`));
  }

  if (!isRecord(payload) || !payload.provider) {
    throw new Error("Provider details were missing from the response.");
  }

  const detail = asCatalogProviderDetail(payload.provider);
  if (!detail) {
    throw new Error("Provider details could not be parsed.");
  }

  return detail;
}

export function useOrgLlmProviders(
  orgId: string | null,
  options: { scope?: "usable" | "manageable" } = {},
) {

View on GitHub (pinned to 2b7df46e8a)

Solutions

  1. Check response.status — 404 means the providerId does not exist server-side; verify the id against GET /v1/llm-provider-catalog.
  2. Re-authenticate if status is 401/403.
  3. Refresh the catalog list so the UI only offers currently-valid provider ids.
  4. Confirm server deployment includes the detail route.

Example fix

// before
throw new Error(getErrorMessage(payload, `Failed to load provider details (${response.status}).`));
// after
if (response.status === 404) throw new Error(`Provider "${providerId}" was not found in the catalog.`);
throw new Error(getErrorMessage(payload, `Failed to load provider details (${response.status}).`));
Defensive patterns

Strategy: try-catch

Validate before calling

// verify the providerId exists in the already-loaded catalog before requesting details
const exists = catalogProviders.some((p) => p.id === providerId);
if (!exists) throw new Error(`Unknown provider: ${providerId}`);

Try / catch

try {
  const detail = await requestLlmProviderCatalogDetail(providerId);
} catch (err) {
  const msg = err instanceof Error ? err.message : String(err);
  if (msg.includes("(404)")) show("Provider not found — refresh the catalog.");
  else show(msg);
}

Prevention

When it happens

Trigger: The detail endpoint returns 401/403, 404 (unknown providerId in the path or route missing), or 5xx; providerId contains characters that, even after encodeURIComponent, resolve to a nonexistent catalog entry server-side.

Common situations: Stale frontend cache referencing a provider id removed from the catalog; typo'd/stale providerId passed from a saved config; session expiry; server version without the detail route.

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 different-ai/openwork@2b7df46e8a (2026-09-01). Data as JSON: /api/errors/789ec0f4b82e2a78. Report an issue: GitHub.