{"record":{"id":"48ecae6ecac742f1","repo":"chroma-core/chroma","slug":"resp-detail-unknown-error","errorCode":null,"errorMessage":"resp.detail || \"Unknown error\"","messagePattern":"resp\\.detail \\|\\| \"Unknown error\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/js/packages/chromadb-core/src/embeddings/CloudflareWorkersAIEmbeddingFunction.ts","lineNumber":79,"sourceCode":"    };\n  }\n\n  public async generate(texts: string[]) {\n    try {\n      const payload = {\n        text: texts,\n      };\n\n      const response = await fetch(this.api_url, {\n        method: \"POST\",\n        headers: this.headers,\n        body: JSON.stringify(payload),\n      });\n\n      const resp = await response.json();\n\n      if (!resp.result || !resp.result.data) {\n        throw new Error(resp.detail || \"Unknown error\");\n      }\n\n      return resp.result.data;\n    } catch (error) {\n      if (error instanceof Error) {\n        throw new Error(\n          `Error calling Cloudflare Workers AI API: ${error.message}`,\n        );\n      } else {\n        throw new Error(`Error calling Cloudflare Workers AI API: ${error}`);\n      }\n    }\n  }\n\n  buildFromConfig(config: StoredConfig): CloudflareWorkersAIEmbeddingFunction {\n    return new CloudflareWorkersAIEmbeddingFunction({\n      model_name: config.model_name,\n      account_id: config.account_id,","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/embeddings/CloudflareWorkersAIEmbeddingFunction.ts#L61-L97","documentation":"In CloudflareWorkersAIEmbeddingFunction.generate, after POSTing to the Workers AI endpoint the code parses the response as JSON and requires resp.result.data to exist. If the payload lacks that shape (typical for Cloudflare error bodies, which carry a detail field), it throws new Error(resp.detail || 'Unknown error'). Because this throw sits inside the surrounding try block, it is immediately re-wrapped, so callers normally see it as 'Error calling Cloudflare Workers AI API: Unknown error' (or ': <detail text>') - the raw message never escapes.","triggerScenarios":"Invalid or expired API key (401 body with detail); wrong account_id or gateway_id (404); unknown model_name; gateway/zone errors returning an error JSON; any 200-less response whose JSON body has no result.data.","commonSituations":"Copied a model name that does not exist for the account; free-tier or rate-limit responses; account/gateway ID mixed up; key rotated server-side while the client still holds the old one.","solutions":["Log the wrapped message's suffix (the detail text) - it is Cloudflare's own error description and pinpoints auth vs model vs account problems.","Verify account_id, gateway_id and model_name against the Cloudflare dashboard; model must be a valid Workers AI model ID like '@cf/baai/bge-small-en-v1.5'.","Confirm the API key is valid with a direct curl to the same URL before retrying through the client.","Handle the wrapped 'Error calling Cloudflare Workers AI API:' error in generate() call sites, since the raw message is never surfaced."],"exampleFix":"// before\nconst embeddings = await ef.generate(['hello']); // throws wrapped 'Unknown error'\n\n// after\ntry {\n  const embeddings = await ef.generate(['hello']);\n} catch (e) {\n  console.error((e as Error).message); // inspect Cloudflare detail text\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const vectors = await ef.generate(texts);\n} catch (e) {\n  const msg = (e as Error).message;\n  if (msg.startsWith('Error calling Cloudflare Workers AI API:')) {\n    const detail = msg.slice('Error calling Cloudflare Workers AI API:'.length).trim();\n    // detail 'Unknown error' or Cloudflare's `detail` text -> auth/account/model issue, not transient\n    throw new Error(`Cloudflare Workers AI rejected the request: ${detail}`);\n  }\n  throw e;\n}","preventionTips":["Validate model_name/account_id/gateway_id against the Cloudflare dashboard once at setup.","Smoke-test the exact endpoint with curl when auth changes.","Surface the wrapped message's detail suffix in logs - it carries Cloudflare's diagnosis."],"tags":["embeddings","cloudflare","api-response","http-error","runtime"],"backgroundTag":"api-error-response","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}