{"record":{"id":"c43f2d119d33082c","repo":"langchain-ai/deepagents","slug":"rubricmiddleware-max-iterations-must-be-an-int","errorCode":null,"errorMessage":"RubricMiddleware: `max_iterations` must be an int, got {type(max_iterations).__name__}.","messagePattern":"RubricMiddleware: `max_iterations` must be an int, got (.+?)\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"libs/deepagents/deepagents/middleware/rubric.py","lineNumber":575,"sourceCode":"        self,\n        *,\n        model: str | BaseChatModel,\n        system_prompt: str | None = None,\n        tools: Sequence[BaseTool] | None = None,\n        grader_middleware: Sequence[AgentMiddleware[Any, Any, Any]] | None = None,\n        grader_context_schema: type[Any] | None = None,\n        grader_state_schema: type[AgentState[Any]] | None = None,\n        prepare_messages_for_grader: Callable[[list[AnyMessage]], list[AnyMessage]] | None = None,\n        build_grader_state: Callable[[RubricState, int], Mapping[str, Any]] | None = None,\n        max_iterations: int = 3,\n        on_evaluation: Callable[[RubricEvaluation], None] | None = None,\n    ) -> None:\n        if not model:\n            msg = \"RubricMiddleware: `model` is required.\"\n            raise ValueError(msg)\n        if not isinstance(max_iterations, int) or isinstance(max_iterations, bool):\n            msg = f\"RubricMiddleware: `max_iterations` must be an int, got {type(max_iterations).__name__}.\"\n            raise TypeError(msg)\n        if max_iterations < 1:\n            msg = f\"RubricMiddleware: `max_iterations` must be positive, got {max_iterations}.\"\n            raise ValueError(msg)\n        if grader_state_schema is None and build_grader_state is not None:\n            msg = \"RubricMiddleware: `grader_state_schema` is required with `build_grader_state`.\"\n            raise ValueError(msg)\n        for name, callback in (\n            (\"prepare_messages_for_grader\", prepare_messages_for_grader),\n            (\"build_grader_state\", build_grader_state),\n        ):\n            if callback is not None and not callable(callback):\n                msg = f\"RubricMiddleware: `{name}` must be callable.\"\n                raise TypeError(msg)\n\n        self.max_iterations = max_iterations\n        self._model = model\n        self._model_label = _configured_model_label(model)\n        self._system_prompt = system_prompt or GRADER_SYSTEM_PROMPT","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/langchain-ai/deepagents/blob/a1af029e6e73cb17c36bff823d227747b28e91e1/libs/deepagents/deepagents/middleware/rubric.py#L557-L593","documentation":"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.","triggerScenarios":"RubricMiddleware(model=..., max_iterations=\"5\") or max_iterations=5.0 or max_iterations=True — any value that is not an int (bool explicitly rejected).","commonSituations":"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.","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."],"exampleFix":"// before\nRubricMiddleware(model=model, max_iterations=os.environ[\"MAX_ITERATIONS\"])\n// after\nRubricMiddleware(model=model, max_iterations=int(os.environ[\"MAX_ITERATIONS\"]))","handlingStrategy":"type-guard","validationCode":"raw = os.environ.get(\"MAX_ITERATIONS\")\nmi = int(raw) if raw is not None else 3\nassert isinstance(mi, int) and not isinstance(mi, bool) and mi >= 1, f\"bad max_iterations: {raw!r}\"","typeGuard":"def is_iteration_count(v: object) -> TypeGuard[int]:\n    return isinstance(v, int) and not isinstance(v, bool)","tryCatchPattern":"try:\n    mw = RubricMiddleware(model=model, max_iterations=mi)\nexcept TypeError as e:\n    if \"max_iterations must be an int\" in str(e):\n        mw = RubricMiddleware(model=model, max_iterations=int(mi))\n    else:\n        raise","preventionTips":["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."],"tags":["python","validation","constructor","type-error"],"backgroundTag":"invalid-parameter-type","analyzedSha":"a1af029e6e73cb17c36bff823d227747b28e91e1","analyzedAt":"2026-08-29T11:43:24.718Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}