{"record":{"id":"65885b078f17db59","repo":"langchain-ai/langchain","slug":"unknown-alternative-which","errorCode":null,"errorMessage":"Unknown alternative: {which}","messagePattern":"Unknown alternative: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"libs/core/langchain_core/runnables/configurable.py","lineNumber":637,"sourceCode":"                \"RunnableConfig\",\n                {\n                    **config,\n                    \"configurable\": {\n                        k.removeprefix(f\"{self.which.id}=={which}/\"): v\n                        for k, v in config.get(\"configurable\", {}).items()\n                    },\n                },\n            )\n        # return the chosen alternative\n        if which == self.default_key:\n            return (self.default, config)\n        if which in self.alternatives:\n            alt = self.alternatives[which]\n            if isinstance(alt, Runnable):\n                return (alt, config)\n            return (alt(), config)\n        msg = f\"Unknown alternative: {which}\"\n        raise ValueError(msg)\n\n\ndef prefix_config_spec(\n    spec: ConfigurableFieldSpec, prefix: str\n) -> ConfigurableFieldSpec:\n    \"\"\"Prefix the id of a `ConfigurableFieldSpec`.\n\n    This is useful when a `RunnableConfigurableAlternatives` is used as a\n    `ConfigurableField` of another `RunnableConfigurableAlternatives`.\n\n    Args:\n        spec: The `ConfigurableFieldSpec` to prefix.\n        prefix: The prefix to add.\n\n    Returns:\n        The prefixed `ConfigurableFieldSpec`.\n    \"\"\"\n    return (","sourceCodeStart":619,"sourceCodeEnd":655,"githubUrl":"https://github.com/langchain-ai/langchain/blob/e32fa9a52eab3b61ad7a45399bfde59b3e580fc4/libs/core/langchain_core/runnables/configurable.py#L619-L655","documentation":"`RunnableConfigurableAlternatives._configure` resolves the requested alternative key from `config[\"configurable\"]`. If the key equals neither `default_key` (typically `'default'`) nor any key in `self.alternatives`, it raises `ValueError: Unknown alternative`. This is the runtime enforcement that only registered alternatives may be selected.","triggerScenarios":"Calling `.with_config(configurable={<field>: 'mistyped_key'})` or `.bind(...)`/invoke-time config on a field created with `ConfigurableField(id=..., options=[...])` / `with_configurable_alternatives(...)`, where the selected key has a typo, wrong casing, or was never registered as an option.","commonSituations":"Selecting `configurable={\"llm\": \"gpt4-turbo\"}` when the option is registered as `'gpt-4-turbo'`; moving configuration between environments where an alternative exists in one deployment's factory but not another; renaming an option id in code but not in persisted configs, prompts, or environment-driven settings; passing the option's value instead of its key.","solutions":["Print the accepted keys first: `runnable.config_schema()` (or inspect `.config_specs()`) to see valid alternative ids.","Correct the key in `with_config(configurable={...})` to exactly match a registered option id (keys are case- and punctuation-sensitive).","If the alternative should exist, register it in `with_configurable_alternatives(...)` / `ConfigurableField` options where the field was declared.","If configs come from user input or a file, validate the key against the schema before invoking the runnable."],"exampleFix":"# before\nllm.with_config(configurable={\"model\": \"gpt4-turbo\"}).invoke(...)  # unregistered key\n\n# after\n# option registered as \"gpt-4-turbo\"\nllm.with_config(configurable={\"model\": \"gpt-4-turbo\"}).invoke(...)","handlingStrategy":"validation","validationCode":"valid_keys = {s[\"id\"] for spec in runnable.config_specs() for s in spec.get(\"alternatives\", [])}\nif key not in valid_keys:\n    raise ValueError(f\"unknown alternative {key!r}; valid: {sorted(valid_keys)}\")\nrunnable.with_config(configurable={field: key}).invoke(...)","typeGuard":null,"tryCatchPattern":"try:\n    out = runnable.with_config(configurable={field: key}).invoke(x)\nexcept ValueError as e:\n    if \"Unknown alternative\" in str(e):\n        # fall back to the declared default alternative\n        out = runnable.invoke(x)\n    else:\n        raise","preventionTips":["Source configurable keys from runnable.config_specs()/config_schema(), never hardcode them.","Treat option ids as case- and punctuation-sensitive API contracts.","Validate user- or file-supplied keys against the schema before invoking."],"tags":["configurable","config","value-error","runtime-config","langchain-core"],"backgroundTag":null,"analyzedSha":"e32fa9a52eab3b61ad7a45399bfde59b3e580fc4","analyzedAt":"2026-08-14T18:42:09.092Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}