{"record":{"id":"665f699c2d097a41","repo":"chroma-core/chroma","slug":"error-calling-together-ai-api-error","errorCode":null,"errorMessage":"Error calling Together AI API: ${error}","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":71,"sourceCode":"        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    };\n  }\n","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/clients/js/packages/chromadb-core/src/embeddings/TogetherAIEmbeddingFunction.ts#L53-L89","documentation":"Fallback branch of the same catch in TogetherAIEmbeddingFunction.generate() for thrown values that are not `instanceof Error` — strings, plain objects, or mock rejections. The raw value is string-interpolated into the message. In practice this almost never comes from Together itself; it comes from custom fetch polyfills, interceptors, or test doubles that reject with non-Error values.","triggerScenarios":"A jest/vitest fetch mock written as `mockRejectedValue('network')`; an old fetch polyfill rejecting with a string or plain object; a service worker / fetch interceptor throwing a non-Error; some environments where DOMException is not an instanceof Error.","commonSituations":"Unit tests mocking global fetch for Chroma; apps with fetch wrappers/interceptors (Sentry, offline caches) installed between the app and the network.","solutions":["Identify who throws the non-Error value: disable fetch mocks/interceptors and rerun.","Update test mocks to reject with `new Error('...')` instead of a string.","Use native fetch (Node >= 18) or a modern polyfill instead of legacy whatwg-fetch versions.","Log the interpolated value — it is the literal thrown value and identifies its source."],"exampleFix":"// before (test mock rejects with a string -> errorIndex 62 branch)\nglobal.fetch = vi.fn().mockRejectedValue(\"network down\");\n\n// after\nglobal.fetch = vi.fn().mockRejectedValue(new Error(\"network down\"));","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await fn.generate(texts);\n} catch (e) {\n  // Normalize: this branch fires only when something threw a non-Error value\n  const err = e instanceof Error ? e : new Error(`Non-Error thrown by fetch layer: ${JSON.stringify(e)}`);\n  throw err;\n}","preventionTips":["Make all fetch mocks and interceptors reject with new Error(...) never plain strings/objects.","Run integration tests with realistic rejections so non-Error throws surface in CI, not prod."],"tags":["together-ai","embeddings","non-error-throw","testing","fetch-mock"],"backgroundTag":"non-error-throw","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}