chroma-core/chroma · error · ValueError

The model name cannot be changed after the embedding functio

Error message

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

What it means

OpenCLIPEmbeddingFunction.get_config() persists {model_name, checkpoint, device} and validate_config_update() raises ValueError if new_config contains "model_name". The model architecture determines the embedding dimension (ViT-B-32 -> 512-dim), so changing it after a collection was populated would store vectors in an incompatible space; Chroma's config protocol therefore treats model_name as create-time-only. Note "checkpoint" is rejected too, while "device" is not checked here.

Source

Thrown at chromadb/utils/embedding_functions/open_clip_embedding_function.py:168

        if model_name is None or checkpoint is None or device is None:
            assert False, "This code should not be reached"

        return OpenCLIPEmbeddingFunction(
            model_name=model_name, checkpoint=checkpoint, device=device
        )

    def get_config(self) -> Dict[str, Any]:
        return {
            "model_name": self.model_name,
            "checkpoint": self.checkpoint,
            "device": self.device,
        }

    def validate_config_update(
        self, old_config: Dict[str, Any], new_config: Dict[str, Any]
    ) -> None:
        if "model_name" in new_config:
            raise ValueError(
                "The model name cannot be changed after the embedding function has been initialized."
            )
        if "checkpoint" in new_config:
            raise ValueError(
                "The checkpoint 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

        Raises:
            ValidationError: If the configuration does not match the schema
        """

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Create a new collection with the new model_name (and matching checkpoint) and re-embed all images
  2. If you only meant to move computation, update "device" (e.g. cpu -> cuda) — that key is allowed
  3. Remove "model_name" (and "checkpoint") from the update payload

Example fix

// before
new_cfg = fn.get_config(); new_cfg["model_name"] = "ViT-L-14"
fn.validate_config_update(fn.get_config(), new_cfg)  # ValueError

// after
fn_l14 = OpenCLIPEmbeddingFunction(model_name="ViT-L-14", checkpoint="laion2b_s32b_b82k")
col2 = client.create_collection("images_vitl14", embedding_function=fn_l14)
# re-add images; new vectors are 768-dim
Defensive patterns

Strategy: validation

Validate before calling

IMMUTABLE = {"model_name", "checkpoint"}
def assert_openclip_update_safe(new_config: dict) -> None:
    blocked = IMMUTABLE & set(new_config)
    if blocked:
        raise ValueError(f"immutable keys {blocked}: create a new collection to change model/checkpoint")

Try / catch

try:
    fn.validate_config_update(old_cfg, new_cfg)
except ValueError as e:
    if "model name cannot be changed" in str(e):
        # route to create-new-collection + re-embed migration
        ...
    raise

Prevention

When it happens

Trigger: Pushing an EF config update containing {"model_name": "ViT-L-14"} via the flow that calls validate_config_update(old_config, new_config); hand-editing persisted EF config JSON to a different model; migration scripts that round-trip get_config(), mutate model_name, and reapply.

Common situations: Upgrading from ViT-B-32 to a better model on an existing image collection; shared config templates applied to many collections with different models; misunderstanding which fields are mutable (only device survives this check).

Related errors


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