{"record":{"id":"fc2fd6fa0e09ab8b","repo":"chroma-core/chroma","slug":"error-calling-together-ai-api-error-message","errorCode":null,"errorMessage":"Error calling Together AI API: ${error.message}","messagePattern":"Error calling Together AI API: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/js/packages/chromadb-core/src/embeddings/TogetherAIEmbeddingFunction.ts","lineNumber":69,"sourceCode":"      const response = await fetch(ENDPOINT, {\n        method: \"POST\",\n        headers: this.headers,\n        body: JSON.stringify(payload),\n      });\n\n      const resp = await response.json();\n\n      if (!resp.data) {\n        throw new Error(\"Invalid response format from Together AI API\");\n      }\n\n      const embeddings = resp.data.map(\n        (item: { embedding: number[] }) => item.embedding,\n      );\n      return embeddings;\n    } catch (error) {\n      if (error instanceof Error) {\n        throw new Error(`Error calling Together AI API: ${error.message}`);\n      } else {\n        throw new Error(`Error calling Together AI API: ${error}`);\n      }\n    }\n  }\n\n  buildFromConfig(config: StoredConfig): IEmbeddingFunction {\n    return new TogetherAIEmbeddingFunction({\n      model_name: config.model_name,\n      api_key_env_var: config.api_key_env_var,\n    });\n  }\n\n  getConfig(): StoredConfig {\n    return {\n      model_name: this.model_name,\n      api_key_env_var: this.api_key_env_var,\n    };","sourceCodeStart":51,"sourceCodeEnd":87,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/embeddings/TogetherAIEmbeddingFunction.ts#L51-L87","documentation":"Catch-all wrapper thrown by TogetherAIEmbeddingFunction.generate() for any Error raised while calling Together AI: fetch network failures, response.json() throwing a SyntaxError on non-JSON bodies (e.g. HTML 502 pages), TypeError when `resp.data` is present but not an array (.map is not a function), or the inner 'Invalid response format' throw whose message gets doubled up. The original cause is preserved as the message suffix, so read everything after 'Error calling Together AI API:'.","triggerScenarios":"fetch() rejects (DNS failure, offline, TLS/proxy cert error, timeout); Together/gateway returns HTML or empty body so response.json() throws SyntaxError \"Unexpected token < in JSON\"; response `data` field is a non-array (error payloads like {data: \"unauthorized\"}).","commonSituations":"Ephemeral network drops in CI pipelines; corporate proxies returning HTML error pages on 502/503; Together API incidents; Node without internet access in a locked-down container.","solutions":["Read the suffix after 'Error calling Together AI API:' — SyntaxError means non-JSON body, TypeError means malformed JSON shape, fetch errors mean network.","For network/5xx causes, retry with backoff (the request is idempotent).","Verify connectivity: curl -i https://api.together.xyz/v1/embeddings from the same host/container.","Check status.together.ai for ongoing incidents."],"exampleFix":"// before\nconst embeddings = await togetherFn.generate(texts); // single shot, any blip fails the job\n\n// after\nconst embeddings = await withRetry(() => togetherFn.generate(texts), {\n  retries: 3,\n  baseDelayMs: 500,\n  isRetryable: (e) => /SyntaxError|fetch failed|ECONN|ETIMEDOUT/i.test(e.message),\n});","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"const RETRYABLE = /fetch failed|ECONN|ETIMEDOUT|ENOTFOUND|SyntaxError|Unexpected token|5[0-9][0-9]/i;\nconst generateWithRetry = async (texts: string[], attempts = 3) => {\n  for (let i = 0; i < attempts; i++) {\n    try {\n      return await fn.generate(texts);\n    } catch (e) {\n      const msg = e instanceof Error ? e.message : String(e);\n      if (i === attempts - 1 || !RETRYABLE.test(msg)) throw e;\n      await new Promise((r) => setTimeout(r, 2 ** i * 500));\n    }\n  }\n  throw new Error(\"unreachable\");\n};","preventionTips":["Treat fetch/json-parse failures from Together as transient and retry with exponential backoff.","Keep ingestion jobs restartable (idempotent ids) so a network blip never corrupts a batch.","Monitor Together status and gate large embedding jobs on a health probe."],"tags":["together-ai","embeddings","network","fetch","json-parse"],"backgroundTag":"embedding-api-request-failed","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}