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

  1. Verify baseURL ends at the API root such that {baseURL}/models resolves (adapter appends the path)
  2. curl {baseURL}/models with the key and inspect the JSON — expect { data: [...] }
  3. If the server uses a different path, set baseURL so the final URL is correct
  4. 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

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


AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27). Data as JSON: /api/errors/35330a6f74b03bb2. Report an issue: GitHub.