linshenkx/prompt-optimizer · error · APIError
Unexpected API response format
Error message
Unexpected API response format
What it means
The response from the OpenAI-compatible /v1/models endpoint did not contain the expected data array (the if-branch that maps models was skipped), so OpenAIAdapter throws the generic 'Unexpected API response format' APIError.
Source
Thrown at packages/core/src/services/llm/adapters/openai-adapter.ts:165
const response = await openai.models.list()
// 检查返回格式
if (response && response.data && Array.isArray(response.data)) {
const models = response.data
.map((model) => {
// 使用buildDefaultModel为每个模型ID创建TextModel对象
return this.buildDefaultModel(model.id)
})
.sort((a, b) => a.id.localeCompare(b.id))
if (models.length === 0) {
throw new APIError('API returned empty model list')
}
return models
}
throw new APIError('Unexpected API response format')
} catch (error: any) {
console.error('[OpenAIAdapter] Failed to fetch models:', error)
// 连接错误处理(包括跨域检测)
if (error.message && (error.message.includes('Failed to fetch') ||
error.message.includes('Connection error'))) {
const isCrossOriginError = this.detectCrossOriginError(error, baseURL)
if (isCrossOriginError) {
throw new APIError(`Cross-origin connection failed: ${error.message}`)
} else {
throw new APIError(`Connection failed: ${error.message}`)
}
}
// API返回的错误信息
if (error.response?.data) {
throw new APIError(`API error: ${JSON.stringify(error.response.data)}`)View on GitHub (pinned to 3e677b1d9f)
Solutions
- Verify baseURL ends at the API root such that {baseURL}/models resolves (adapter appends the path)
- curl {baseURL}/models with the key and inspect the JSON — expect { data: [...] }
- If the server uses a different path, set baseURL so the final URL is correct
- Upgrade the adapter/gateway if the server's models schema diverged
Example fix
// before
baseURL: 'https://my-gw.example.com'
// after
baseURL: 'https://my-gw.example.com/v1' // so GET {baseURL}/models returns { data: [...] } Defensive patterns
Strategy: validation
Validate before calling
const r = await fetch(`${baseURL.replace(/\/$/, '')}/models`, { headers: { Authorization: `Bearer ${key}` } })
const body = await r.json()
if (!Array.isArray(body?.data)) throw new Error(`${baseURL} is not a valid OpenAI-compatible models endpoint`) Type guard
function isOpenAIModelsResponse(d: unknown): d is { data: { id: string }[] } {
return Array.isArray((d as any)?.data) && (d as any).data.every((m: any) => typeof m?.id === 'string')
} Try / catch
null
Prevention
- Set baseURL to the API root (usually ends with /v1)
- Verify endpoints with curl before configuring
- Prefer official provider base URLs over guessed ones
When it happens
Trigger: Base URL points at a server returning JSON without data (e.g. an error object with 200), an HTML page, or a differently-versioned models endpoint; response.json() parsed fine but the shape check failed.
Common situations: Wrong baseURL (pointing at a dashboard URL instead of the API root), Azure-style endpoints needing a query param, proxies returning wrapped responses.
Related errors
- Unexpected API response format
- Cloudflare model search returned an unexpected response form
- API returned empty model list
- API returned invalid response: choices is empty or missing
- No valid response received
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/35330a6f74b03bb2.
Report an issue: GitHub.