different-ai/openwork · error
Provider details were missing from the response.
Error message
Provider details were missing from the response.
What it means
When the provider-detail endpoint responds 2xx, the payload must be an object containing a truthy `provider` field. If the body is not a record or lacks `provider`, this error is thrown instead of returning undefined downstream.
Source
Thrown at ee/apps/den-web/app/(den)/dashboard/_components/llm-provider-data.tsx:488
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" } = {},
) {
const [llmProviders, setLlmProviders] = useState<DenLlmProvider[]>([]);
const [busy, setBusy] = useState(false);
const [error, setError] = useState<string | null>(null);
const scope = options.scope ?? "manageable";View on GitHub (pinned to 2b7df46e8a)
Solutions
- Log the raw payload and confirm the server is expected to return `{ provider: {...} }`.
- Update the client parser if the server renamed the field.
- Fix the server handler to always include `provider` in successful responses.
- Bypass/clear intermediary caches to rule out empty cached 200s.
Example fix
// before (server detail handler)
return NextResponse.json(detail);
// after
return NextResponse.json({ provider: detail }); Defensive patterns
Strategy: type-guard
Validate before calling
function hasProviderField(p: unknown): boolean {
return typeof p === "object" && p !== null && "provider" in p;
}
// check on the parsed JSON before calling the request helper's downstream logic Type guard
const isRecord = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v !== null && !Array.isArray(v);
function hasProvider(v: unknown): v is { provider: Record<string, unknown> } {
return isRecord(v) && isRecord(v.provider);
} Try / catch
try {
const detail = await requestLlmProviderCatalogDetail(providerId);
} catch (err) {
if (err instanceof Error && err.message === "Provider details were missing from the response.") {
console.error("Detail endpoint returned 200 without provider — check API contract");
} else throw err;
} Prevention
- Lock the response envelope ({ provider }) with a shared schema test.
- Return non-ok (e.g. 404) instead of empty 200s when the provider is missing.
- Clear CDN/proxy caches after API shape changes.
- Version the detail route if the envelope must change.
When it happens
Trigger: GET /v1/llm-provider-catalog/:providerId returns 200 with a body that is not an object (null, array, string) or lacks the `provider` key — e.g. an empty 200 from a proxy, or a server contract change wrapping the detail differently.
Common situations: Version skew between den-web and den-api after renaming/moving the `provider` field; caching layers returning empty 200s; test doubles returning incomplete bodies.
Related errors
- Provider details could not be parsed.
- Library response was incomplete.
- Endpoint test returned an unexpected response.
- Inference settings response was incomplete.
- Failed to load the provider catalog (${response.status}).
AI-assisted analysis of different-ai/openwork@2b7df46e8a (2026-09-01).
Data as JSON: /api/errors/0c795a50fc562e5c.
Report an issue: GitHub.