{"record":{"id":"7a95397a219f0964","repo":"chroma-core/chroma","slug":"error-calling-jina-ai-api-error-message","errorCode":null,"errorMessage":"Error calling Jina AI API: ${error.message}","messagePattern":"Error calling Jina AI API: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/js/packages/chromadb-core/src/embeddings/JinaEmbeddingFunction.ts","lineNumber":132,"sourceCode":"    try {\n      const response = await fetch(this.api_url, {\n        method: \"POST\",\n        headers: this.headers,\n        body: JSON.stringify(json_body),\n      });\n\n      const data = (await response.json()) as { data: any[]; detail: string };\n      if (!data || !data.data) {\n        throw new Error(data.detail);\n      }\n\n      const embeddings: any[] = data.data;\n      const sortedEmbeddings = embeddings.sort((a, b) => a.index - b.index);\n\n      return sortedEmbeddings.map((result) => result.embedding);\n    } catch (error) {\n      if (error instanceof Error) {\n        throw new Error(`Error calling Jina AI API: ${error.message}`);\n      } else {\n        throw new Error(`Error calling Jina AI API: ${error}`);\n      }\n    }\n  }\n\n  buildFromConfig(config: StoredConfig): JinaEmbeddingFunction {\n    return new JinaEmbeddingFunction({\n      model_name: config.model_name,\n      api_key_env_var: config.api_key_env_var,\n      task: config.task,\n      late_chunking: config.late_chunking,\n      truncate: config.truncate,\n      dimensions: config.dimensions,\n      embedding_type: config.embedding_type,\n      normalized: config.normalized,\n    });\n  }","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/embeddings/JinaEmbeddingFunction.ts#L114-L150","documentation":"The outer catch in JinaEmbeddingFunction.generate() wraps every failure — fetch network errors (DNS, ECONNREFUSED, TLS), JSON parse errors on non-JSON bodies, and even the inner data.detail Error from error 50 (yielding 'Error calling Jina AI API: <server detail>') — into a single prefixed Error. Only the message text survives; the original error class, stack context, and cause chain are lost.","triggerScenarios":"api.jina.ai unreachable (offline environment, blocked egress, proxy misconfiguration); a proxy/captive portal returning an HTML error page so response.json() throws; or the inner !data.data branch throwing first and being re-wrapped here.","commonSituations":"Corporate proxies blocking api.jina.ai; air-gapped environments; misconfigured HTTPS_PROXY; double-wrapped detail errors making logs noisy and hard to alert on.","solutions":["Inspect the text after 'Error calling Jina AI API:' — it carries the root cause (e.g. 'fetch failed', 'Invalid API key')","Reproduce connectivity from the same host/container: curl -sS https://api.jina.ai/v1/embeddings to distinguish network from auth issues","Add api.jina.ai to proxy/egress allowlists or fix proxy env vars","If the suffix is a Jina detail string, apply the fix for that underlying error (key, quota, model)"],"exampleFix":"// before (library code): opaque wrapper loses the cause\nthrow new Error(`Error calling Jina AI API: ${error.message}`);\n\n// after (library-level): rethrow untouched so stack/cause survive\nthrow error;","handlingStrategy":"try-catch","validationCode":"async function jinaReachable(): Promise<boolean> {\n  try {\n    await fetch(\"https://api.jina.ai\", { method: \"HEAD\", signal: AbortSignal.timeout(5_000) });\n    return true; // any HTTP answer proves DNS/TLS/egress work\n  } catch {\n    return false;\n  }\n}\n// run at startup in restricted-network environments","typeGuard":null,"tryCatchPattern":"try {\n  const vecs = await ef.generate(texts);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.startsWith(\"Error calling Jina AI API:\")) {\n    const cause = msg.slice(\"Error calling Jina AI API:\".length).trim();\n    // classify: 'fetch failed' -> network/egress; anything else -> server detail (auth/quota/model)\n  }\n  throw e;\n}","preventionTips":["Add api.jina.ai to proxy/egress allowlists and verify HTTPS_PROXY settings in containers","Set explicit fetch timeouts so hung requests fail fast instead of blocking batches","Log the unwrapped cause text; the library's wrapper hides the original error class"],"tags":["jina","network","embeddings","error-wrapping","fetch","proxy"],"backgroundTag":"upstream-api-error","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}