langchain-ai/deepagents · error · ValueError
RubricMiddleware: `build_grader_state` cannot set `messages`
Error message
RubricMiddleware: `build_grader_state` cannot set `messages`.
What it means
`build_grader_state` customizes the grader's input state, but `messages` is reserved: the middleware always sets messages itself to a single HumanMessage containing the built grader payload. A builder that returns a dict containing a `messages` key would overwrite that payload, so it's rejected at runtime with ValueError.
Source
Thrown at libs/deepagents/deepagents/middleware/rubric.py:1011
keeps untrusted transcript content from being read as instructions.
Args:
state: Agent state, read for the rubric and transcript.
iteration: Zero-based grading iteration.
correction: Feedback about a previous unusable response, if any.
Returns:
The nested grader's input state.
"""
grader_state = state
if self._prepare_messages_for_grader:
grader_state = RubricState(**state)
grader_state["messages"] = self._prepare_messages_for_grader(list(state.get("messages", [])))
payload = self._build_grader_payload(grader_state, iteration, correction)
grader_input = dict(self._build_grader_state(grader_state, iteration)) if self._build_grader_state else {}
if "messages" in grader_input:
msg = "RubricMiddleware: `build_grader_state` cannot set `messages`."
raise ValueError(msg)
grader_input["messages"] = [HumanMessage(content=payload)]
return grader_input
def _invoke_grader(
self,
state: RubricState,
iteration: int,
correction: str | None = None,
*,
context: object | None = None,
) -> GraderResponse:
"""Run one grader call while preserving nested graph inputs.
This is the per-call extension point beneath `_grade`'s coverage retry.
Overrides should forward `correction` and `context` when delegating here.
The context is LangGraph's static runtime context, passed through so a
nested grader using a context schema receives the same run dependencies.
Grader input must continue through `_grader_input`, which delegates toView on GitHub (pinned to a1af029e6e)
Solutions
- Return a dict without the `messages` key: {k: v for k, v in state.items() if k != 'messages'}.
- Use prepare_messages_for_grader if you want to shape the conversation content shown to the grader.
- Pass custom instructions via system_prompt instead of injecting messages.
- Extend grader_state_schema for extra context fields rather than messages.
Example fix
// before
def build_grader_state(state, iteration):
return dict(state) # includes messages
// after
def build_grader_state(state, iteration):
return {k: v for k, v in state.items() if k != "messages"} | {"iteration": iteration} Defensive patterns
Strategy: try-catch
Validate before calling
def my_builder(state, iteration):
out = {k: v for k, v in state.items() if k != "messages"}
assert "messages" not in out
return out Type guard
def is_grader_input(d: dict) -> bool:
return "messages" not in d Try / catch
try:
result = middleware._invoke_grader(state)
except ValueError as e:
if "cannot set `messages`" in str(e):
fix_builder_to_exclude_messages()
else:
raise Prevention
- In build_grader_state, filter out 'messages' instead of passing state through wholesale.
- Use prepare_messages_for_grader for message shaping — that's its job.
- Keep builders returning only extra context keys declared in grader_state_schema.
- Add a unit test asserting the builder output has no 'messages' key.
When it happens
Trigger: A build_grader_state callback that does dict(state) or returns a state including state["messages"] instead of only extra keys.
Common situations: Copy-pasting the full state into the builder output; trying to inject custom messages/examples for the grader (the supported route is prepare_messages_for_grader or the payload via system_prompt).
Related errors
- RubricMiddleware grader did not return a structured_response
- shell.allow_list is missing from the configuration manifest
- max_retries must be >= 0
- StateBackend must be used inside a LangGraph graph execution
- StateBackend requires CONFIG_KEY_READ / CONFIG_KEY_SEND in t
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/5d81b96e4bbd5436.
Report an issue: GitHub.