chroma-core/chroma · error · Error

Error calling Together AI API: ${error}

Error message

Error calling Together AI API: ${error}

What it means

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.

Source

Thrown at clients/js/packages/chromadb-core/src/embeddings/TogetherAIEmbeddingFunction.ts:71

        headers: this.headers,
        body: JSON.stringify(payload),
      });

      const resp = await response.json();

      if (!resp.data) {
        throw new Error("Invalid response format from Together AI API");
      }

      const embeddings = resp.data.map(
        (item: { embedding: number[] }) => item.embedding,
      );
      return embeddings;
    } catch (error) {
      if (error instanceof Error) {
        throw new Error(`Error calling Together AI API: ${error.message}`);
      } else {
        throw new Error(`Error calling Together AI API: ${error}`);
      }
    }
  }

  buildFromConfig(config: StoredConfig): IEmbeddingFunction {
    return new TogetherAIEmbeddingFunction({
      model_name: config.model_name,
      api_key_env_var: config.api_key_env_var,
    });
  }

  getConfig(): StoredConfig {
    return {
      model_name: this.model_name,
      api_key_env_var: this.api_key_env_var,
    };
  }

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Identify who throws the non-Error value: disable fetch mocks/interceptors and rerun.
  2. Update test mocks to reject with `new Error('...')` instead of a string.
  3. Use native fetch (Node >= 18) or a modern polyfill instead of legacy whatwg-fetch versions.
  4. Log the interpolated value — it is the literal thrown value and identifies its source.

Example fix

// before (test mock rejects with a string -> errorIndex 62 branch)
global.fetch = vi.fn().mockRejectedValue("network down");

// after
global.fetch = vi.fn().mockRejectedValue(new Error("network down"));
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await fn.generate(texts);
} catch (e) {
  // Normalize: this branch fires only when something threw a non-Error value
  const err = e instanceof Error ? e : new Error(`Non-Error thrown by fetch layer: ${JSON.stringify(e)}`);
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: Unit tests mocking global fetch for Chroma; apps with fetch wrappers/interceptors (Sentry, offline caches) installed between the app and the network.

Related errors


AI-assisted analysis of chroma-core/chroma@aecdd12c8a (2026-08-16). Data as JSON: /api/errors/665f699c2d097a41. Report an issue: GitHub.