linshenkx/prompt-optimizer · error · APIError
Cloudflare model search returned an unexpected response form
Error message
Cloudflare model search returned an unexpected response format
What it means
Cloudflare's model search endpoint returned HTTP 200 but the JSON body failed the shape check: it must have success===true and result as an array. The adapter treats this as an unexpected contract violation rather than trying to read fields from it.
Source
Thrown at packages/core/src/services/llm/adapters/cloudflare-adapter.ts:80
public async getModelsAsync(config: TextModelConfig): Promise<TextModel[]> {
const accountId = this.getAccountId(config);
const baseURL = this.resolveCloudflareManagementBaseURL(config.connectionConfig.baseURL, accountId);
const url = `${baseURL}/models/search?task=${encodeURIComponent('Text Generation')}&hide_experimental=true&per_page=100`;
const response = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${config.connectionConfig.apiKey || ''}`
}
});
if (!response.ok) {
throw new APIError(`Cloudflare model search failed: ${await this.getErrorMessage(response)}`);
}
const data = await response.json();
if (!data?.success || !Array.isArray(data?.result)) {
throw new APIError('Cloudflare model search returned an unexpected response format');
}
const models = data.result
.filter((model: CloudflareModelSearchResult) => {
return model?.task?.name === 'Text Generation' && typeof model?.name === 'string' && !!model.name.trim();
})
.map((model: CloudflareModelSearchResult) => this.mapDynamicModel(model));
return models.length > 0 ? models : this.getModels();
}
public getModels(): TextModel[] {
return CLOUDFLARE_STATIC_MODELS.map((definition) => {
const baseModel = this.buildDefaultModel(definition.id);
return {
...baseModel,
name: definition.name,View on GitHub (pinned to 3e677b1d9f)
Solutions
- curl the model search URL manually and inspect the payload for { success, result }
- Remove custom base URL overrides so the adapter uses the default Cloudflare endpoint
- Upgrade the package if Cloudflare changed the schema and a fix shipped
- Fall back to a static list of Cloudflare models in the UI when this format error occurs
Example fix
// before
const models = await adapter.getModelsAsync()
// after
let models
try { models = await adapter.getModelsAsync() }
catch (e) {
if (e instanceof APIError && e.message.includes('unexpected response format')) {
models = DEFAULT_CLOUDFLARE_MODELS
} else throw e
} Defensive patterns
Strategy: fallback
Validate before calling
null
Type guard
function isCloudflareSearchResult(d: unknown): d is { success: true; result: unknown[] } {
return !!(d as any)?.success && Array.isArray((d as any).result)
} Try / catch
try { models = await adapter.getModelsAsync() }
catch (e) {
if (e instanceof APIError && e.message.includes('unexpected response format')) models = FALLBACK_CF_MODELS
else throw e
} Prevention
- Avoid overriding the Cloudflare base URL/path
- Pin package versions against known-good Cloudflare API behavior
- Test model listing in CI against the real endpoint
When it happens
Trigger: Cloudflare changes/versions the search API response schema, an intermediate proxy rewrites the response, or a paginated/different endpoint is accidentally targeted via a custom base URL.
Common situations: Custom resolveCloudflareApiBaseURL overrides pointing at the wrong path, gateway mangling responses, upstream API evolution.
Related errors
- Unexpected API response format
- Unexpected API response format
- Invalid import data format
- Cloudflare model search failed: ${await this.getErrorMessage
- Cloudflare requires accountId in connection config
AI-assisted analysis of linshenkx/prompt-optimizer@3e677b1d9f (2026-08-27).
Data as JSON: /api/errors/b662d3526e44b724.
Report an issue: GitHub.