linshenkx/prompt-optimizer · error · APIError

Cloudflare model search failed: ${await this.getErrorMessage

Error message

Cloudflare model search failed: ${await this.getErrorMessage(response)}

What it means

CloudflareAdapter.getModelsAsync calls Cloudflare's model search REST endpoint with a Bearer token; when the HTTP response is not ok it throws APIError with the status and body text extracted by getErrorMessage. This covers auth failures and bad requests against the Cloudflare AI Gateway/Workers AI catalog API.

Source

Thrown at packages/core/src/services/llm/adapters/cloudflare-adapter.ts:75

        }
      }
    };
  }

  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) => {

View on GitHub (pinned to 3e677b1d9f)

Solutions

  1. Inspect the appended status/body: 401 → create a new API token with Workers AI permissions
  2. Verify connectionConfig.apiKey is set and is the Cloudflare token (not an OpenAI key)
  3. Check accountId matches the Cloudflare account (see getAccountId)
  4. Check Cloudflare status page for ongoing incidents if 5xx

Example fix

// before
const models = await adapter.getModelsAsync()

// after
try {
  const models = await adapter.getModelsAsync()
} catch (e: any) {
  if (e instanceof APIError && e.message.includes('model search failed')) {
    logAndNotify('Cloudflare model listing failed', e.message)
  }
  throw e
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

function isCloudflareHttpError(e: unknown): boolean {
  return e instanceof APIError && e.message.includes('Cloudflare model search failed')
}

Try / catch

try { models = await adapter.getModelsAsync() }
catch (e) {
  if (isCloudflareHttpError(e)) { notify(e.message); models = [] }
  else throw e
}

Prevention

When it happens

Trigger: Calling getModelsAsync() with an invalid API token (401), wrong account ID producing 403/404, malformed query, or Cloudflare API incidents (5xx).

Common situations: Expired/revoked Cloudflare API token, token missing 'Workers AI / Model read' permissions, wrong accountId in connection config.

Related errors


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