chroma-core/chroma · error · ValueError

An embedding function already exists in the collection confi

Error message

An embedding function already exists in the collection configuration, and a new one is provided. If this is intentional, please embed documents separately. Embedding function conflict: new: {embedding_function.name()} vs persisted: {persisted_ef_config.get('name')}

What it means

This ValueError from validate_embedding_function_conflict_on_get fires when you call get_collection (or list/restore paths that re-open collections) with an embedding_function whose name differs from the one persisted in the collection's configuration. Chroma protects against silently querying a collection with an incompatible embedding model, since vectors embedded differently would return garbage results.

Source

Thrown at chromadb/api/collection_configuration.py:806

# The reason to use the config on get, rather than build the ef is because
# if there is an issue with deserializing the config, an error shouldn't be raised
# at get time. CollectionCommon.py will raise an error at _embed time if there is an issue deserializing.
def validate_embedding_function_conflict_on_get(
    embedding_function: Optional[EmbeddingFunction],  # type: ignore
    persisted_ef_config: Optional[Dict[str, Any]],
) -> None:
    """
    Validates that there are no conflicting embedding functions between function parameter
    and collection configuration.
    """
    if persisted_ef_config is not None and embedding_function is not None:
        if (
            embedding_function.name() != "default"
            and persisted_ef_config.get("name") is not None
            and persisted_ef_config.get("name") != embedding_function.name()
        ):
            raise ValueError(
                f"An embedding function already exists in the collection configuration, and a new one is provided. If this is intentional, please embed documents separately. Embedding function conflict: new: {embedding_function.name()} vs persisted: {persisted_ef_config.get('name')}"
            )
    return None


def update_schema_from_collection_configuration(
    schema: "Schema", configuration: "UpdateCollectionConfiguration"
) -> "Schema":
    """
    Updates a schema with configuration changes.
    Only updates fields that are present in the configuration update.

    Args:
        schema: The existing Schema object
        configuration: The configuration updates to apply

    Returns:
        Updated Schema object

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Call get_collection with the SAME embedding function class that created the collection (same name()), or pass no embedding_function to use the persisted one
  2. If you intentionally changed embedding models, create a new collection and re-embed the source documents; do not read old vectors with the new EF
  3. If the persisted EF is what you want, rely on the stored configuration instead of passing embedding_function

Example fix

// before
# collection was created with SentenceTransformerEmbeddingFunction
col = client.get_collection(
    'docs', embedding_function=OpenAIEmbeddingFunction(api_key=KEY)
)  # ValueError on get

// after
col = client.get_collection('docs')  # uses persisted EF config
# or explicitly the same function:
col = client.get_collection(
    'docs', embedding_function=SentenceTransformerEmbeddingFunction()
)
Defensive patterns

Strategy: validation

Validate before calling

def ef_matches_persisted(persisted_cfg: dict | None, ef) -> bool:
    if persisted_cfg is None or ef is None:
        return True
    name = persisted_cfg.get('name')
    return name is None or ef.name() == 'default' or ef.name() == name

col_cfg = client.get_collection('docs').configuration  # or fetch metadata first
# if ef_matches_persisted(col_cfg.get('embedding_function'), my_ef):
col = client.get_collection('docs', embedding_function=my_ef)

Type guard

def ef_matches_persisted(persisted_cfg, ef) -> bool:
    if persisted_cfg is None or ef is None:
        return True
    name = persisted_cfg.get('name')
    return name is None or ef.name() == 'default' or ef.name() == name

Try / catch

try:
    col = client.get_collection('docs', embedding_function=my_ef)
except ValueError as e:
    if 'Embedding function conflict' in str(e):
        col = client.get_collection('docs')  # rely on persisted EF config
    else:
        raise

Prevention

When it happens

Trigger: Creating a collection with EF A (e.g. OpenAIEmbeddingFunction) and later calling client.get_collection('name', embedding_function=EF_B) where EF_B.name() != 'default' and != persisted name. Common after swapping embedding providers in app config without recreating collections, or in tests that use a different EF than production code that created the data.

Common situations: Changing the embedding model in settings/environment between runs; multiple services sharing a persisted Chroma directory with different EFs configured; refactoring from the default EF to a custom one while reusing the same on-disk database; CI tests creating data with one EF and reading with another.

Related errors


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