langchain-ai/langchain · error · ValueError
Expected keys {sorted(expected_keys)} do not match parameter
Error message
Expected keys {sorted(expected_keys)} do not match parameter names {sorted(parameter_names)} of get_session_history. What it means
When more than one key is expected (multi-parameter get_session_history or multiple history_factory_config fields), RunnableWithMessageHistory invokes the callable by keyword arguments and requires that the set of expected keys exactly equals the set of parameter names in get_session_history's signature. Any mismatch raises this ValueError listing both sets.
Source
Thrown at libs/core/langchain_core/runnables/history.py:619
if len(expected_keys) == 1:
if parameter_names:
# If arity = 1, then invoke function by positional arguments
message_history = self.get_session_history(
configurable[expected_keys[0]]
)
else:
if not config:
config["configurable"] = {}
message_history = self.get_session_history()
else:
# otherwise verify that names of keys patch and invoke by named arguments
if set(expected_keys) != set(parameter_names):
msg = (
f"Expected keys {sorted(expected_keys)} do not match parameter "
f"names {sorted(parameter_names)} of get_session_history."
)
raise ValueError(msg)
message_history = self.get_session_history(
**{key: configurable[key] for key in expected_keys}
)
config["configurable"]["message_history"] = message_history
return config
def _get_parameter_names(callable_: GetSessionHistoryCallable) -> list[str]:
"""Get the parameter names of the `Callable`."""
sig = inspect.signature(callable_)
return list(sig.parameters.keys())
View on GitHub (pinned to e32fa9a52e)
Solutions
- Align the ConfigurableFieldSpec ids with the get_session_history parameter names exactly (or vice versa)
- Simplify: if possible use a single-parameter factory taking just session_id
- Verify with inspect.signature(get_session_history) and compare against the field ids you pass to history_factory_config
Example fix
# before
def get_history(session_id: str, tenant: str): ...
history_factory_config=[
ConfigurableFieldSpec(id="session_id", ...),
ConfigurableFieldSpec(id="tenant_id", ...), # mismatch: param is `tenant`
]
# after
ConfigurableFieldSpec(id="tenant", ...) # matches parameter name Defensive patterns
Strategy: validation
Validate before calling
import inspect
params = set(inspect.signature(get_session_history).parameters)
expected = {f.id for f in history_factory_config}
assert params == expected, f"{params} != {expected}" Try / catch
try:
wrapped.invoke(x, cfg)
except ValueError as e:
if "do not match parameter" in str(e):
fix_field_ids_to_match_signature() Prevention
- Make ConfigurableFieldSpec ids literally equal the factory's parameter names
- Simplest: single-parameter get_session_history(session_id)
When it happens
Trigger: A get_session_history(session_id, user_id) factory but history_factory_config declaring fields named differently (e.g. session_id, tenant_id); declaring two ConfigurableFieldSpec ids that do not match the function parameters.
Common situations: Multi-tenant history stores keyed by (user_id, session_id); refactoring parameter names without updating ConfigurableFieldSpec ids; copying a factory from docs with different naming.
Related errors
- Missing keys {sorted(missing_keys)} in config['configurable'
- Expected a single list of messages. Got {input_val}.
- Expected str, BaseMessage, list[BaseMessage], or tuple[BaseM
- Expected str, BaseMessage, list[BaseMessage], or tuple[BaseM
- Loading {config_type} prompt not supported
AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14).
Data as JSON: /api/errors/79267287e5a17501.
Report an issue: GitHub.