chroma-core/chroma · error · ChromaValueError

Embedding function provided when already defined in the coll

Error message

Embedding function provided when already defined in the collection configuration

What it means

Thrown by serializeEmbeddingFunction in the Chroma JS client when an embedding function is supplied through two channels at once: the direct embeddingFunction argument AND configuration.embeddingFunction. Chroma requires the embedding function to be declared through exactly one source, because two functions could disagree on how documents are embedded and stored. This is a client-side ChromaValueError raised before any network request is made (called from collection-configuration.ts:79 during createCollection and :231 during modify).

Source

Thrown at clients/new-js/packages/chromadb/src/embedding-function.ts:336

    return undefined;
  }
};

/**
 * Serializes an embedding function to configuration format.
 * @param embeddingFunction - User provided embedding function
 * @param configEmbeddingFunction - Collection config embedding function
 * @returns Configuration object that can recreate the function
 */
export const serializeEmbeddingFunction = ({
  embeddingFunction,
  configEmbeddingFunction,
}: {
  embeddingFunction?: EmbeddingFunction;
  configEmbeddingFunction?: EmbeddingFunction;
}): EmbeddingFunctionConfiguration | undefined => {
  if (embeddingFunction && configEmbeddingFunction) {
    throw new ChromaValueError(
      "Embedding function provided when already defined in the collection configuration",
    );
  }

  if (!embeddingFunction && !configEmbeddingFunction) {
    return undefined;
  }

  const ef = embeddingFunction || configEmbeddingFunction!;
  if (
    !ef.getConfig ||
    !ef.name ||
    !(ef.constructor as EmbeddingFunctionClass).buildFromConfig
  ) {
    return { type: "legacy" };
  }

  if (ef.validateConfig) ef.validateConfig(ef.getConfig());

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Pass the embedding function in exactly ONE place: either the embeddingFunction argument or configuration.embeddingFunction — delete the other
  2. Prefer moving it into configuration.embeddingFunction so the function is recorded in the collection's persisted configuration, and drop the positional argument
  3. If a shared helper injects a default embedding function, make it skip injection when the caller already provided one

Example fix

// before
const col = await client.createCollection("docs", myEF, {
  embeddingFunction: myEF, // second source -> ChromaValueError
});

// after
const col = await client.createCollection("docs", undefined, {
  embeddingFunction: myEF, // single source
});
Defensive patterns

Strategy: validation

Validate before calling

function assertSingleEmbeddingSource(
  ef: EmbeddingFunction | null | undefined,
  config: CreateCollectionConfiguration | undefined,
) {
  const sources = [ef, config?.embeddingFunction].filter((s) => s != null);
  if (sources.length > 1) {
    throw new Error(
      "Pass the embedding function either as an argument or in configuration.embeddingFunction, not both",
    );
  }
}
assertSingleEmbeddingSource(myEF, config);
await client.createCollection(name, myEF, config);

Type guard

const hasSingleEmbeddingSource = (
  ef: unknown,
  configEf: unknown,
): boolean => [ef, configEf].filter((v) => v != null).length <= 1;

Try / catch

try {
  await client.createCollection(name, myEF, config);
} catch (e) {
  if (e instanceof ChromaValueError && /already defined/.test(e.message)) {
    // remove one of the two embedding function sources and retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Calling client.createCollection(name, myEF, { embeddingFunction: otherEF }) with both the positional/argument embedding function and configuration.embeddingFunction set. Also triggered by collection modification paths that pass a new embedding function while the collection configuration already carries one.

Common situations: Migrating pre-1.9 Chroma JS client code that passed the embedding function as an argument, then adding the newer configuration-object style without removing the old argument. Copy-pasting an example that uses configuration.embeddingFunction into code that already passes ef. A shared wrapper/helper that injects a default embedding function while the caller also supplies one.

Related errors


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