linshenkx/prompt-optimizer · warning · APIError
API returned empty model list
Error message
API returned empty model list
What it means
OpenAIAdapter.getModelsAsync successfully fetched a models array (data: [...]) but after filtering/mapping it produced zero entries, so it throws rather than return an empty list — the endpoint is reachable and the shape is right, but there is nothing usable.
Source
Thrown at packages/core/src/services/llm/adapters/openai-adapter.ts:159
// 验证baseURL以/v1结尾
const baseURL = config.connectionConfig.baseURL || this.getProvider().defaultBaseURL
const openai = this.createOpenAIInstance(config, false)
try {
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}`)View on GitHub (pinned to 3e677b1d9f)
Solutions
- Check the backing server actually serves models: curl $BASE_URL/v1/models
- If local, load/pull a model (ollama pull, vllm serve ...) before listing
- If a project-scoped key is used, grant the project access to at least one model
- Treat this as a non-fatal empty state in UI rather than crashing
Example fix
// before
const models = await adapter.getModelsAsync()
setModels(models)
// after
let models: TextModel[] = []
try { models = await adapter.getModelsAsync() }
catch (e) { if (!(e instanceof APIError && /empty model list/.test(e.message))) throw e }
setModels(models) // render empty state gracefully Defensive patterns
Strategy: try-catch
Validate before calling
const resp = await fetch(`${baseURL}/models`, { headers })
const body = await resp.json()
if (!Array.isArray(body?.data) || body.data.length === 0) warn('No models available on server') Type guard
null
Try / catch
try { models = await adapter.getModelsAsync() }
catch (e) {
if (e instanceof APIError && /empty model list/.test(e.message)) models = []
else throw e
} Prevention
- Ensure at least one model is loaded/pulled on local gateways
- Grant model access to project-scoped keys
- Treat empty lists as a UI state, not an exception
When it happens
Trigger: Listing models from a server whose model list is empty, entries filtered out because model.id is missing/non-string, or a gateway exposing zero deployed models.
Common situations: Local gateways (vLLM/llama.cpp/Ollama bridges) with no models loaded yet, an OpenAI-compatible service where all entries lack the id field, freshly provisioned projects with no model access granted.
Related errors
- Unexpected API response format
- UNSUPPORTED_TEST_TYPE
- Unexpected API response format
- Cloudflare model search returned an unexpected response form
- Cross-origin connection failed: ${error.message}
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/917573cddeec10d7.
Report an issue: GitHub.