{"record":{"id":"4f9125051fabf1da","repo":"linshenkx/prompt-optimizer","slug":"cloudflare-requires-accountid-in-connection-config","errorCode":null,"errorMessage":"Cloudflare requires accountId in connection config","messagePattern":"Cloudflare requires accountId in connection config","errorType":"exception","errorClass":"RequestConfigError","httpStatus":null,"severity":"error","filePath":"packages/core/src/services/llm/adapters/cloudflare-adapter.ts","lineNumber":131,"sourceCode":"\n  protected createOpenAIInstance(config: TextModelConfig, isStream: boolean = false): OpenAI {\n    const accountId = this.getAccountId(config);\n\n    const normalizedConfig: TextModelConfig = {\n      ...config,\n      connectionConfig: {\n        ...config.connectionConfig,\n        baseURL: this.resolveCloudflareApiBaseURL(config.connectionConfig.baseURL, accountId)\n      }\n    };\n\n    return super.createOpenAIInstance(normalizedConfig, isStream);\n  }\n\n  private getAccountId(config: TextModelConfig): string {\n    const accountId = String(config.connectionConfig.accountId || '').trim();\n    if (!accountId) {\n      throw new RequestConfigError('Cloudflare requires accountId in connection config');\n    }\n\n    return accountId;\n  }\n\n  private resolveCloudflareApiBaseURL(rawBaseURL: string | undefined, accountId: string): string {\n    const providerBaseURL = this.getProvider().defaultBaseURL;\n    let baseURL = (rawBaseURL || providerBaseURL).trim();\n\n    if (baseURL.endsWith('/chat/completions')) {\n      baseURL = baseURL.slice(0, -'/chat/completions'.length);\n    }\n\n    const encodedAccountId = encodeURIComponent(accountId);\n    const trimmed = baseURL.replace(/\\/$/, '');\n\n    if (trimmed.includes('{accountId}')) {\n      return trimmed.replace('{accountId}', encodedAccountId);","sourceCodeStart":113,"sourceCodeEnd":149,"githubUrl":"https://github.com/linshenkx/prompt-optimizer/blob/3e677b1d9f7e0493c142c175560531e7ae786dce/packages/core/src/services/llm/adapters/cloudflare-adapter.ts#L113-L149","documentation":"Cloudflare's Workers AI REST API requires the account ID in the URL path. getAccountId reads connectionConfig.accountId, trims it, and throws RequestConfigError if empty — every Cloudflare call needs it to build https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/...","triggerScenarios":"Creating a Cloudflare provider config without accountId in connectionConfig; passing only apiKey; accountId being whitespace or a non-string that String()s to ''.","commonSituations":"Copying an API token but forgetting the account ID, config forms that only ask for the key, YAML/JSON config where the field is misnamed (account_id vs accountId).","solutions":["Add accountId to connectionConfig: it's on the Cloudflare dashboard right side / URL after login (dash.cloudflare.com/<accountId>)","Confirm the field name is exactly accountId (camelCase) inside connectionConfig","Ensure the value survives normalization (no empty string, not undefined)","Pre-validate config before creating the adapter (see validation code)"],"exampleFix":"// before\nconst config = { connectionConfig: { apiKey: CF_TOKEN } }\n\n// after\nconst config = {\n  connectionConfig: { apiKey: CF_TOKEN, accountId: CF_ACCOUNT_ID }\n}","handlingStrategy":"validation","validationCode":"function validateCloudflareConfig(cfg: TextModelConfig) {\n  const id = String(cfg.connectionConfig?.accountId || '').trim()\n  if (!id) throw new Error('Missing Cloudflare accountId')\n  if (!/^\\w{10,}$/.test(id)) throw new Error('accountId looks invalid')\n}","typeGuard":"function hasAccountId(cfg: TextModelConfig): boolean {\n  return typeof cfg.connectionConfig?.accountId === 'string' && cfg.connectionConfig.accountId.trim().length > 0\n}","tryCatchPattern":"null","preventionTips":["Validate config in provider forms before save","Store accountId next to apiKey in secrets management","Copy the account ID straight from the Cloudflare dashboard URL"],"tags":["cloudflare","account-id","config","missing-parameter"],"backgroundTag":"missing-required-config","analyzedSha":"3e677b1d9f7e0493c142c175560531e7ae786dce","analyzedAt":"2026-08-27T21:29:16.709Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}