langchain-ai/deepagents · error · TypeError
max_retries must be an int, got {type(max_retries).__name__}
Error message
max_retries must be an int, got {type(max_retries).__name__} What it means
The retry wrapper's constructor validates that `max_retries` is a true integer before computing the attempt budget. Because `bool` is an `int` subclass in Python, `True >= 0` would silently pass and `range(True + 1)` would run two attempts, so booleans are rejected explicitly. A `TypeError` is raised naming the actual type received.
Source
Thrown at libs/code/deepagents_code/model_retry.py:1067
max_retries: Startup fallback for retry attempts after the initial
call. `0` disables retries unless the request's runtime-selected
model carries a different provider-specific budget.
stream_output_is_visible: Whether message-stream chunks emitted by
this model reach a user-visible consumer; it decides the
`output_may_have_started` supersession flag on retry events.
Keep `True` unless the entire nested stream is filtered before
rendering.
Raises:
TypeError: If `max_retries` or `stream_output_is_visible` has the
wrong type.
ValueError: If `max_retries` is negative.
"""
# `True >= 0` passes and `range(True + 1)` runs two attempts, so an
# unchecked bool reads as a budget of one retry.
if isinstance(max_retries, bool):
msg = f"max_retries must be an int, got {type(max_retries).__name__}"
raise TypeError(msg)
if max_retries < 0:
msg = "max_retries must be >= 0"
raise ValueError(msg)
if not isinstance(stream_output_is_visible, bool):
msg = (
"stream_output_is_visible must be a bool, got "
f"{type(stream_output_is_visible).__name__}"
)
raise TypeError(msg)
self.max_retries = max_retries
self.stream_output_is_visible = stream_output_is_visible
@staticmethod
def _emit_stream_event(request: ModelRequest, event: dict[str, object]) -> None:
writer = getattr(getattr(request, "runtime", None), "stream_writer", None)
if writer is None:
return
try:View on GitHub (pinned to a1af029e6e)
Solutions
- Pass an explicit integer, e.g. `max_retries=1` instead of `True`
- Coerce config values with `int(value)` before constructing, guarding against bools
- If the source is a boolean flag, decide the intended count and map it explicitly (True -> 2, False -> 0)
Example fix
// before model = RetryModel(inner, max_retries=True) // after model = RetryModel(inner, max_retries=1 if flag else 0)
Defensive patterns
Strategy: type-guard
Validate before calling
if isinstance(max_retries, bool) or not isinstance(max_retries, int) or max_retries < 0:
raise ValueError(f"max_retries must be a non-negative int, got {max_retries!r}") Type guard
def is_valid_max_retries(v: object) -> TypeGuard[int]:
return isinstance(v, int) and not isinstance(v, bool) and v >= 0 Prevention
- Never pass booleans where a count is expected; map flags to explicit ints
- Validate config values at load time, before model construction
- Use mypy/pyright strict typing so bool vs int misuse is flagged
When it happens
Trigger: Passing `max_retries=True` or `max_retries=False` (e.g. from a loosely-typed config value or a flag misused as a count) when constructing the retry-wrapped model in `__init__`.
Common situations: YAML/JSON configs where `true`/`false` is loaded as a bool and fed straight into the model constructor; refactoring a `retry=True` flag into `max_retries`; environment variables parsed with a truthiness shortcut.
Related errors
- interpreter_ptc must be False, 'safe', 'all', or a list of t
- max_retries must be >= 0
- stream_output_is_visible must be a bool, got {type(stream_ou
- context.{key} must be a string or null, got {type(value).__n
- context.{key} must be an object, got {type(value).__name__}.
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/e7aa6faa8bc073b0.
Report an issue: GitHub.