chroma-core/chroma · error · ValueError

The model cannot be changed after the embedding function has

Error message

The model cannot be changed after the embedding function has been initialized.

What it means

NomicEmbeddingFunction implements Chroma's embedding-function configuration protocol: get_config() serializes its constructor params and validate_config_update() rejects any update that includes the "model" key. Because embeddings for a given collection must stay dimensionally and semantically compatible, the model is pinned at creation; changing nomic-embed-text-v1 to v1.5 after documents were embedded would silently poison the index, so Chroma refuses it.

Source

Thrown at chromadb/utils/embedding_functions/nomic_embedding_function.py:117

            model=model,
            api_key_env_var=api_key_env_var,
            task_type=task_type,
            query_config=query_config,
        )

    def get_config(self) -> Dict[str, Any]:
        return {
            "model": self.model,
            "api_key_env_var": self.api_key_env_var,
            "task_type": self.task_type,
            "query_config": self.query_config,
        }

    def validate_config_update(
        self, old_config: Dict[str, Any], new_config: Dict[str, Any]
    ) -> None:
        if "model" in new_config:
            raise ValueError(
                "The model cannot be changed after the embedding function has been initialized."
            )

    @staticmethod
    def validate_config(config: Dict[str, Any]) -> None:
        """
        Validate the configuration using the JSON schema.

        Args:
            config: Configuration to validate
        """
        validate_config_schema(config, "nomic")

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Create a NEW embedding function (and typically a new collection) with the desired model instead of updating the existing one
  2. Re-embed all documents into the new collection, then delete the old one: read docs from the old collection, add them with the new EF
  3. Remove the "model" key from the update payload if you only meant to change other fields (none are currently mutable for Nomic besides rebuilding)

Example fix

// before (rejected)
new_config = fn.get_config(); new_config["model"] = "nomic-embed-text-v1.5"
fn.validate_config_update(fn.get_config(), new_config)  # ValueError

// after
fn_v15 = NomicEmbeddingFunction(model="nomic-embed-text-v1.5", task_type="search_document", query_config={"task_type": "search_query"})
col2 = client.create_collection("docs_v15", embedding_function=fn_v15)
for batch in col.get(include=["documents","metadatas"])["documents"]: ...  # re-ingest
Defensive patterns

Strategy: validation

Validate before calling

IMMUTABLE = {"model"}
def safe_ef_update(fn, new_config: dict) -> dict:
    blocked = IMMUTABLE & set(new_config)
    if blocked:
        raise ValueError(f"Cannot update immutable EF keys {blocked}; create a new collection instead")
    return new_config

Try / catch

try:
    fn.validate_config_update(old_config, new_config)
except ValueError as e:
    if "cannot be changed" in str(e):
        # branch to migration path: new collection + re-embed
        ...
    raise

Prevention

When it happens

Trigger: Calling the EF config-update API path with a new config dict containing {"model": ...} (e.g. via collection-level EF reconfiguration or the config-management flow that calls validate_config_update(old_config, new_config)); attempting to reuse a persisted EF config while swapping only the model field.

Common situations: Upgrading from nomic-embed-text-v1 to nomic-embed-text-v1.5 and trying to hot-swap the model on an existing collection; editing EF config JSON by hand and including the model key; tooling that round-trips get_config() output and mutates model before reapplying it.

Related errors


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