chatboxai/chatbox · error · ApiError
JSON.stringify(json)
Error message
JSON.stringify(json)
What it means
Thrown by OpenAICompatibleSDK.listModels when the GET {apiHost}/models response JSON lacks a `data` array. The entire parsed JSON is JSON.stringify'd into the ApiError message so the caller sees the unexpected payload. This is a contract violation: the OpenAI-compatible /models endpoint must return { data: [{ id }, ...] }.
Source
Thrown at src/shared/models/openai-compatible.ts:159
) {
const headers = {
Authorization: `Bearer ${params.apiKey}`,
...(params.extraHeaders || {}),
}
const response = params.customFetch
? await params.customFetch(`${params.apiHost}/models`, {
method: 'GET',
headers,
})
: await dependencies.request.apiRequest({
url: `${params.apiHost}/models`,
method: 'GET',
headers,
useProxy: params.useProxy,
})
const json: ListModelsResponse = await response.json()
if (!json.data) {
throw new ApiError(JSON.stringify(json))
}
return json.data.map((item) => {
const modelInfo: ProviderModelInfo = {
modelId: item.id,
type: 'chat',
}
// Add nickname from OpenRouter name field
if (item.name) {
modelInfo.nickname = item.name
}
// Add context window if available
if (item.context_length) {
modelInfo.contextWindow = item.context_length
}
// Add capabilities based on architectureView on GitHub (pinned to 81571269ad)
Solutions
- Verify apiHost points to an OpenAI-compatible /models endpoint and the API key has permission to list models.
- Open apiHost/models in a browser/curl and confirm the response shape is { data: [{ id: '...' }, ...] }; if not, switch provider type or fix the host.
- Remove trailing slashes and duplicate '/v1' segments in apiHost.
- Improve the error to surface response.status alongside the body so auth vs. shape issues are distinguishable.
Example fix
// before
const json: ListModelsResponse = await response.json()
if (!json.data) {
throw new ApiError(JSON.stringify(json))
}
// after — include status and a hint
const json: ListModelsResponse = await response.json()
if (!json.data) {
throw new ApiError(`listModels: no 'data' field (status ${response.status}): ${JSON.stringify(json)}`)
} Defensive patterns
Strategy: validation
Validate before calling
// Smoke-test the /models endpoint shape before relying on it.
async function modelsEndpointIsOpenAICompatible(apiHost: string, headers: Record<string,string>): Promise<boolean> {
try {
const res = await fetch(`${apiHost.replace(/\/$/, '')}/models`, { headers })
const json = await res.json().catch(() => null)
return Boolean(json && Array.isArray(json.data))
} catch { return false }
} Type guard
function isListModelsResponse(v: unknown): v is { data: { id: string }[] } {
return typeof v === 'object' && v !== null && Array.isArray((v as any).data)
} Try / catch
try {
return await sdk.listModels()
} catch (e) {
if (e instanceof ApiError) {
// e.message is JSON.stringify(json); parse it back to inspect
const body = JSON.parse(e.message)
if (body.error) showUser(`Provider error: ${body.error.message ?? body.error}`)
else showUser('Unexpected /models response — check apiHost and API key.')
return []
}
throw e
} Prevention
- Confirm apiHost points to an OpenAI-compatible API and includes the correct path prefix (/v1).
- Remove trailing slashes and duplicate /v1 segments in apiHost.
- Validate the API key has permission to list models before calling.
When it happens
Trigger: response.json() resolves to an object without a `data` field — e.g. the endpoint returned an error envelope ({ error: {...} }), an HTML page parsed as empty, an auth challenge, or a non-OpenAI schema (Anthropic-style, Google-style).
Common situations: Wrong apiHost (pointed at a non-OpenAI-compatible API); missing/invalid API key causing a JSON error body; endpoint requires a different path (e.g. /v1/models vs /models); self-hosted server returns its own error shape; apiHost includes a trailing slash doubling the path.
Related errors
- Custom provider "${providerId}" conflicts with a builtin pro
- Unknown transport type
- Unsupported search provider: ${provider}
- third_party_parser_not_supported_in_chat
- document_parser_not_configured
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/02a1049adc0f6222.
Report an issue: GitHub.