{"record":{"id":"e4cdc65b0c4e7fb2","repo":"chroma-core/chroma","slug":"invalid-response-format-from-together-ai-api","errorCode":null,"errorMessage":"Invalid response format from Together AI API","messagePattern":"Invalid response format from Together AI API","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"clients/js/packages/chromadb-core/src/embeddings/TogetherAIEmbeddingFunction.ts","lineNumber":60,"sourceCode":"  }\n\n  public async generate(texts: string[]): Promise<number[][]> {\n    try {\n      const payload = {\n        model: this.model_name,\n        input: texts,\n      };\n\n      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,","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/embeddings/TogetherAIEmbeddingFunction.ts#L42-L78","documentation":"Thrown by TogetherAIEmbeddingFunction.generate() when the response from Together AI's POST https://api.together.xyz/v1/embeddings parses as JSON but has no `data` array. The client expects the OpenAI-style shape `{ data: [{ embedding: [...] }] }` and never checks `response.ok`/`response.status` first, so any JSON error body (auth error, unknown model, rate limit) lands here. Note the surrounding catch immediately re-wraps it as 'Error calling Together AI API: Invalid response format from Together AI API'.","triggerScenarios":"Any collection.add({ids, documents}) or collection.query() that makes TogetherAIEmbeddingFunction call the endpoint with: an invalid/expired API key (Bearer token rejected, body like {message:...}), a model_name that is not a Together embeddings model, a 429/5xx whose JSON body lacks `data`, or a proxy returning a JSON error envelope.","commonSituations":"CHROMA_TOGETHER_AI_API_KEY (or custom api_key_env_var) unset or wrong in CI/deploy env; passing a chat/completion model name (e.g. 'meta-llama/Llama-3-8b') instead of an embeddings model (e.g. 'BAAI/bge-base-en-v1.5', 'togethercomputer/m2-bert-80M-8k-retrieval'); corporate gateway intercepting the request; Together API incident.","solutions":["Reproduce the exact request with curl to see the real error body: curl -s https://api.together.xyz/v1/embeddings -H \"Authorization: Bearer $CHROMA_TOGETHER_AI_API_KEY\" -H \"Content-Type: application/json\" -d '{\"model\":\"BAAI/bge-base-en-v1.5\",\"input\":[\"hi\"]}'","Fix the API key: pass together_ai_api_key in the constructor or export CHROMA_TOGETHER_AI_API_KEY.","Fix model_name: use a model listed under 'Embeddings' in Together's model catalog.","If behind a proxy/firewall, confirm it does not rewrite the response body, and test the same fetch outside Chroma."],"exampleFix":"// before\nnew TogetherAIEmbeddingFunction({\n  model_name: \"meta-llama/Llama-3-8b-chat-hf\", // not an embeddings model -> API returns error JSON without `data`\n});\nawait collection.add({ ids: [\"1\"], documents: [\"hello\"] }); // throws\n\n// after\nnew TogetherAIEmbeddingFunction({\n  model_name: \"BAAI/bge-base-en-v1.5\", // Together embeddings model\n  api_key_env_var: \"CHROMA_TOGETHER_AI_API_KEY\",\n});\nawait collection.add({ ids: [\"1\"], documents: [\"hello\"] });","handlingStrategy":"try-catch","validationCode":"// Startup smoke test: fail fast with the real API error before ingesting data\nconst fn = new TogetherAIEmbeddingFunction({\n  model_name: \"BAAI/bge-base-en-v1.5\",\n  together_ai_api_key: process.env.CHROMA_TOGETHER_AI_API_KEY,\n});\nconst probe = await fn.generate([\"ping\"]);\nif (!probe?.length || !probe[0]?.length) throw new Error(\"Together AI embeddings misconfigured\");","typeGuard":null,"tryCatchPattern":"try {\n  await collection.add({ ids, documents });\n} catch (e) {\n  const msg = e instanceof Error ? e.message : String(e);\n  if (msg.includes(\"Invalid response format from Together AI API\")) {\n    throw new Error(\"Together AI rejected the embedding request (bad API key or model_name): check CHROMA_TOGETHER_AI_API_KEY and the model catalog\", { cause: e });\n  }\n  throw e;\n}","preventionTips":["Run a one-text generate() smoke test at app startup instead of discovering key/model problems mid-ingestion.","Set together_ai_api_key explicitly in CI rather than relying on ambient env vars.","Pin model_name to a Together embeddings model and review it when the client library is upgraded."],"tags":["together-ai","embeddings","api-response","authentication","http"],"backgroundTag":"unexpected-api-response-format","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}