langchain-ai/langchain · error · ValueError
If 'exception_key' is specified then inputs must be dictiona
Error message
If 'exception_key' is specified then inputs must be dictionaries.However found a type of {type(inputs[0])} for input What it means
`RunnableWithFallbacks.batch` validates every element of `inputs` is a `dict` when `exception_key` is set, because each failing run's error is written into its corresponding input dict for the fallbacks to see. If any element is not a dict, `ValueError` is raised before batching starts; the message reports the type of the first element.
Source
Thrown at libs/core/langchain_core/runnables/fallbacks.py:280
raise first_error
@override
def batch(
self,
inputs: list[Input],
config: RunnableConfig | list[RunnableConfig] | None = None,
*,
return_exceptions: bool = False,
**kwargs: Any | None,
) -> list[Output]:
if self.exception_key is not None and not all(
isinstance(input_, dict) for input_ in inputs
):
msg = (
"If 'exception_key' is specified then inputs must be dictionaries."
f"However found a type of {type(inputs[0])} for input"
)
raise ValueError(msg)
if not inputs:
return []
# setup callbacks
configs = get_config_list(config, len(inputs))
callback_managers = [
CallbackManager.configure(
inheritable_callbacks=config.get("callbacks"),
local_callbacks=None,
verbose=False,
inheritable_tags=config.get("tags"),
local_tags=None,
inheritable_metadata=config.get("metadata"),
local_metadata=None,
)
for config in configs
]View on GitHub (pinned to e32fa9a52e)
Solutions
- Normalize every input to a dict before batching: `[x if isinstance(x, dict) else {"text": x} for x in inputs]`.
- Remove `exception_key` from `with_fallbacks` if per-item error capture is unnecessary.
- Add a validation pass that rejects/logs non-dict entries at ingestion time.
Example fix
# before
outs = fb.batch(prompts) # prompts: list[str], fb has exception_key
# after
outs = fb.batch([{"text": p} for p in prompts]) Defensive patterns
Strategy: validation
Validate before calling
inputs = [x if isinstance(x, dict) else {"text": x} for x in inputs]
fb.batch(inputs) Type guard
from typing import TypeGuard
def all_dicts(xs: list[object]) -> TypeGuard[list[dict]]:
return all(isinstance(x, dict) for x in xs) Prevention
- Normalize batch items to dicts at the producer boundary.
- Reject or log non-dict entries at ingestion instead of at batch time.
- Avoid exception_key unless every batch item is a mutable dict.
When it happens
Trigger: `fb.batch(["a", "b"])` or `fb.batch([dict_input, string_input])` on a runnable created with `.with_fallbacks(..., exception_key="errors")`; mixing formats when batching heterogeneous requests; a producer that sometimes yields strings instead of payload dicts.
Common situations: Batching prompts as strings with a fallback-wrapped parser; a queue consumer where some messages are already dicts and others are raw text; reusing the `exception_key` feature with legacy string inputs after upgrading the pipeline.
Related errors
- If 'exception_key' is specified then input must be a diction
- length must be >= 0, but got {length}
- config must be a list of the same length as inputs, but got
- Argument 'prompts' is expected to be of type list[str], rece
- callbacks must be the same length as prompts
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/d7be18a2094bd2e8.
Report an issue: GitHub.