diff --git a/libs/langgraph/langgraph/graph/state.py b/libs/langgraph/langgraph/graph/state.py index 3d370d721..5810aaf29 100644 --- a/libs/langgraph/langgraph/graph/state.py +++ b/libs/langgraph/langgraph/graph/state.py @@ -725,14 +725,14 @@ def _is_field_binop(typ: Type[Any]) -> Optional[BinaryOperatorAggregate]: if len(meta) >= 1 and callable(meta[-1]): sig = signature(meta[0]) params = list(sig.parameters.values()) - if len(params) == 2 and len( - [ - p - for p in params - if p.kind in (p.POSITIONAL_ONLY, p.POSITIONAL_OR_KEYWORD) - ] + if len(params) == 2 and all( + p.kind in (p.POSITIONAL_ONLY, p.POSITIONAL_OR_KEYWORD) for p in params ): return BinaryOperatorAggregate(typ, meta[0]) + else: + raise ValueError( + f"Invalid reducer signature. Expected (a, b) -> c. Got {sig}" + ) return None diff --git a/libs/langgraph/tests/test_pregel.py b/libs/langgraph/tests/test_pregel.py index 844f069ea..4ab248098 100644 --- a/libs/langgraph/tests/test_pregel.py +++ b/libs/langgraph/tests/test_pregel.py @@ -185,6 +185,15 @@ def test_graph_validation() -> None: with pytest.raises(ValueError, match="Found edge starting at unknown node "): graph.compile() + def bad_reducer(a): + ... + + class BadReducerState(TypedDict): + hello: Annotated[str, bad_reducer] + + with pytest.raises(ValueError, match="Invalid reducer"): + StateGraph(BadReducerState) + def test_checkpoint_errors() -> None: class FaultyGetCheckpointer(MemorySaver):