{"record":{"id":"ea9fd1e1e1a60965","repo":"chroma-core/chroma","slug":"multiple-embedding-functions-provided-please-prov-ea9fd1","errorCode":null,"errorMessage":"Multiple embedding functions provided. Please provide only one. Embedding function conflict: {embedding_function.name()} vs {configuration_ef.name()}","messagePattern":"Multiple embedding functions provided\\. Please provide only one\\. Embedding function conflict: (.+?) vs (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"chromadb/api/collection_configuration.py","lineNumber":783,"sourceCode":"    Validates that there are no conflicting embedding functions between function parameter\n    and collection configuration.\n\n    Args:\n        embedding_function: The embedding function provided as a parameter\n        configuration_ef: The embedding function from collection configuration\n\n    Returns:\n        bool: True if there is a conflict, False otherwise\n    \"\"\"\n    # If ef provided in function params and collection config, check if they are the same\n    # If not, there's a conflict\n    # ef is by default \"default\" if not provided, so ignore that case.\n    if embedding_function is not None and configuration_ef is not None:\n        if (\n            embedding_function.name() != \"default\"\n            and embedding_function.name() != configuration_ef.name()\n        ):\n            raise ValueError(\n                f\"Multiple embedding functions provided. Please provide only one. Embedding function conflict: {embedding_function.name()} vs {configuration_ef.name()}\"\n            )\n    return None\n\n\n# The reason to use the config on get, rather than build the ef is because\n# if there is an issue with deserializing the config, an error shouldn't be raised\n# at get time. CollectionCommon.py will raise an error at _embed time if there is an issue deserializing.\ndef validate_embedding_function_conflict_on_get(\n    embedding_function: Optional[EmbeddingFunction],  # type: ignore\n    persisted_ef_config: Optional[Dict[str, Any]],\n) -> None:\n    \"\"\"\n    Validates that there are no conflicting embedding functions between function parameter\n    and collection configuration.\n    \"\"\"\n    if persisted_ef_config is not None and embedding_function is not None:\n        if (","sourceCodeStart":765,"sourceCodeEnd":801,"githubUrl":"https://github.com/chroma-core/chroma/blob/aecdd12c8a891610db8653630b066b32ceb678b5/chromadb/api/collection_configuration.py#L765-L801","documentation":"This ValueError from validate_embedding_function_conflict (on the create path) fires when an embedding function is passed BOTH as the embedding_function= argument AND inside the collection configuration, and the two are different (neither is the 'default' placeholder). Chroma refuses to guess which function owns the collection's embedding space, so it rejects the ambiguous request.","triggerScenarios":"Calling client.create_collection(name='c', embedding_function=my_ef, configuration=CollectionConfiguration(embedding_function=other_ef)) where my_ef.name() != other_ef.name() and my_ef.name() != 'default'. Also triggered by wrappers (LangChain, LlamaIndex) that inject their own embedding_function while the user also supplies a configuration embedding function.","commonSituations":"Adopting the new collection configuration API while keeping the legacy embedding_function= kwarg out of habit; framework integrations passing both implicitly; copy-pasting configuration examples into code that already sets embedding_function.","solutions":["Provide the embedding function in exactly ONE place: either the configuration or the embedding_function argument, not both","If both exist in your code path, drop the legacy embedding_function= kwarg and keep the configuration one","Make sure the two are truly identical when a framework injects one for you"],"exampleFix":"// before\nclient.create_collection(\n    name='docs',\n    embedding_function=SentenceTransformerEmbeddingFunction(),\n    configuration=CollectionConfiguration(\n        embedding_function=OpenAIEmbeddingFunction(api_key=KEY)\n    ),\n)  # ValueError: conflict\n\n// after\nclient.create_collection(\n    name='docs',\n    configuration=CollectionConfiguration(\n        embedding_function=OpenAIEmbeddingFunction(api_key=KEY)\n    ),\n)","handlingStrategy":"validation","validationCode":"def embedding_functions_consistent(kwarg_ef, config_ef) -> bool:\n    if kwarg_ef is None or config_ef is None:\n        return True\n    return kwarg_ef.name() == 'default' or kwarg_ef.name() == config_ef.name()\n\nassert embedding_functions_consistent(my_ef, cfg.get('embedding_function'))\nclient.create_collection(name='c', embedding_function=my_ef, configuration=cfg)","typeGuard":"def embedding_functions_consistent(kwarg_ef, config_ef) -> bool:\n    if kwarg_ef is None or config_ef is None:\n        return True\n    return kwarg_ef.name() == 'default' or kwarg_ef.name() == config_ef.name()","tryCatchPattern":"try:\n    client.create_collection(name='c', embedding_function=my_ef, configuration=cfg)\nexcept ValueError as e:\n    if 'Multiple embedding functions provided' in str(e):\n        client.create_collection(name='c', configuration=cfg)  # config wins, kwarg dropped\n    else:\n        raise","preventionTips":["Adopt one convention (config-based EF) and delete legacy embedding_function= usage","Wrap collection creation in a helper that refuses both inputs","In framework integrations (LangChain etc.), check whether the wrapper already injects an EF before adding yours"],"tags":["chroma","embedding-function","create-collection","conflict","configuration"],"backgroundTag":"embedding-function-mismatch","analyzedSha":"aecdd12c8a891610db8653630b066b32ceb678b5","analyzedAt":"2026-08-16T21:53:27.228Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}