langchain-ai/deepagents · error · TypeError
RubricMiddleware: `max_iterations` must be an int, got {type
Error message
RubricMiddleware: `max_iterations` must be an int, got {type(max_iterations).__name__}. What it means
RubricMiddleware validates that `max_iterations` is an int (and not a bool, which is a subclass of int in Python) at construction time. Passing a non-int like a string or float is almost always a config parsing mistake. The middleware refuses to start with an ambiguous iteration limit rather than failing later mid-grading loop.
Source
Thrown at libs/deepagents/deepagents/middleware/rubric.py:575
self,
*,
model: str | BaseChatModel,
system_prompt: str | None = None,
tools: Sequence[BaseTool] | None = None,
grader_middleware: Sequence[AgentMiddleware[Any, Any, Any]] | None = None,
grader_context_schema: type[Any] | None = None,
grader_state_schema: type[AgentState[Any]] | None = None,
prepare_messages_for_grader: Callable[[list[AnyMessage]], list[AnyMessage]] | None = None,
build_grader_state: Callable[[RubricState, int], Mapping[str, Any]] | None = None,
max_iterations: int = 3,
on_evaluation: Callable[[RubricEvaluation], None] | None = None,
) -> None:
if not model:
msg = "RubricMiddleware: `model` is required."
raise ValueError(msg)
if not isinstance(max_iterations, int) or isinstance(max_iterations, bool):
msg = f"RubricMiddleware: `max_iterations` must be an int, got {type(max_iterations).__name__}."
raise TypeError(msg)
if max_iterations < 1:
msg = f"RubricMiddleware: `max_iterations` must be positive, got {max_iterations}."
raise ValueError(msg)
if grader_state_schema is None and build_grader_state is not None:
msg = "RubricMiddleware: `grader_state_schema` is required with `build_grader_state`."
raise ValueError(msg)
for name, callback in (
("prepare_messages_for_grader", prepare_messages_for_grader),
("build_grader_state", build_grader_state),
):
if callback is not None and not callable(callback):
msg = f"RubricMiddleware: `{name}` must be callable."
raise TypeError(msg)
self.max_iterations = max_iterations
self._model = model
self._model_label = _configured_model_label(model)
self._system_prompt = system_prompt or GRADER_SYSTEM_PROMPTView on GitHub (pinned to a1af029e6e)
Solutions
- Convert the value to int before constructing: max_iterations=int(raw).
- If it comes from a config/env, parse with int(os.environ["MAX_ITERATIONS"]) or a schema validator (pydantic).
- Pass a plain int literal, e.g. max_iterations=3.
- If the value is optional, pass the library default instead of None-wrapped variants that end up bool.
Example fix
// before RubricMiddleware(model=model, max_iterations=os.environ["MAX_ITERATIONS"]) // after RubricMiddleware(model=model, max_iterations=int(os.environ["MAX_ITERATIONS"]))
Defensive patterns
Strategy: type-guard
Validate before calling
raw = os.environ.get("MAX_ITERATIONS")
mi = int(raw) if raw is not None else 3
assert isinstance(mi, int) and not isinstance(mi, bool) and mi >= 1, f"bad max_iterations: {raw!r}" Type guard
def is_iteration_count(v: object) -> TypeGuard[int]:
return isinstance(v, int) and not isinstance(v, bool) Try / catch
try:
mw = RubricMiddleware(model=model, max_iterations=mi)
except TypeError as e:
if "max_iterations must be an int" in str(e):
mw = RubricMiddleware(model=model, max_iterations=int(mi))
else:
raise Prevention
- Parse env/config numerics with int() immediately at load time.
- Use pydantic settings models for numeric config fields.
- Never pass bools as counts; bool is an int subclass and is explicitly rejected.
- Add a constructor-level smoke test for your config wiring.
When it happens
Trigger: RubricMiddleware(model=..., max_iterations="5") or max_iterations=5.0 or max_iterations=True — any value that is not an int (bool explicitly rejected).
Common situations: Reading max_iterations from env vars or YAML/JSON config where everything is a string; copying a float from a tuning script; accidentally passing a bool flag.
Related errors
- RubricMiddleware: `{name}` must be callable.
- interpreter_ptc must be False, 'safe', 'all', or a list of t
- max_retries must be an int, got {type(max_retries).__name__}
- stream_output_is_visible must be a bool, got {type(stream_ou
- context.{key} must be a string or null, got {type(value).__n
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/c43f2d119d33082c.
Report an issue: GitHub.