chroma-core/chroma · error · Error

The model name cannot be changed after initialization.

Error message

The model name cannot be changed after initialization.

What it means

Chroma validates changes to an embedding configuration by calling validateConfigUpdate(oldConfig, newConfig). The Google embedding function refuses model_name changes: vectors already stored in the collection were produced by the old model, and mixing embedding spaces silently corrupts similarity search. The model is therefore pinned for the life of the collection's config.

Source

Thrown at clients/js/packages/chromadb-core/src/embeddings/GoogleGeminiEmbeddingFunction.ts:121

      apiKeyEnvVar: config.api_key_env_var,
      taskType: config.task_type,
    });
  }

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

  validateConfigUpdate(
    oldConfig: Record<string, any>,
    newConfig: Record<string, any>,
  ): void {
    if (oldConfig.model_name !== newConfig.model_name) {
      throw new Error("The model name cannot be changed after initialization.");
    }

    if (oldConfig.taskType !== newConfig.taskType) {
      throw new Error("The task type cannot be changed after initialization.");
    }
  }

  validateConfig(config: Record<string, any>): void {
    validateConfigSchema(config, "google_generative_ai");
  }
}

View on GitHub (pinned to aecdd12c8a)

Solutions

  1. Keep model_name identical: fetch the stored getConfig() first and reuse its model_name when updating other fields
  2. If the model must change, create a NEW collection with the new model and re-embed all source documents into it (backfill job)
  3. If the existing data is disposable, delete and recreate the collection with the new model

Example fix

// before: bumping the model on an existing collection
const ef = new GoogleGenerativeAiEmbeddingFunction({ googleApiKey: KEY, model: "text-embedding-004" });
// validateConfigUpdate(old{model_name:'embedding-001'}, new{model_name:'text-embedding-004'}) -> throws

// after: new collection per model
const v2 = await client.createCollection({ name: "docs-embedding-004", embeddingFunction: ef });
await v2.add({ ids, documents }); // re-embed from source
Defensive patterns

Strategy: validation

Validate before calling

function assertCompatibleUpdate(oldCfg: Record<string, any>, newCfg: Record<string, any>): void {
  if (oldCfg.model_name !== newCfg.model_name) {
    throw new Error(`model_name is immutable (${oldCfg.model_name} -> ${newCfg.model_name}); create a new collection instead`);
  }
}
// call this BEFORE requesting the config update, using getConfig() output as oldCfg

Try / catch

try {
  await applyConfigUpdate(collection, newCfg);
} catch (e) {
  if (e instanceof Error && /model name cannot be changed/i.test(e.message)) {
    // route to the create-new-collection + re-embed path instead of retrying
  }
  throw e;
}

Prevention

When it happens

Trigger: An embedding-config update where newConfig.model_name differs from oldConfig.model_name — e.g. re-creating the function with model: "text-embedding-004" and applying it to a collection embedded with "embedding-001". Other fields may still be updated; only model_name is checked here.

Common situations: Upgrading Gemini embedding model versions in an existing deployment; per-environment config templates injecting different model names onto existing collections; hand-edited config backups being restored.

Related errors


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