langchain-ai/deepagents · error · TypeError
cli_max_retries must be None or an int, got {self.cli_max_re
Error message
cli_max_retries must be None or an int, got {self.cli_max_retries!r} What it means
`ModelResult.__post_init__` raising TypeError because `cli_max_retries` is a bool instead of None or an int. Same rationale as model_retries: `True` would silently act as a retry budget of 1.
Source
Thrown at libs/code/deepagents_code/config.py:5578
it was the one budget field in dcode without the check -- which is the
argument for a single validated budget type rather than a ninth copy of
this predicate.
Raises:
TypeError: If `model_retries` or `cli_max_retries` is a `bool`.
ValueError: If `model_retries` or `cli_max_retries` is negative.
"""
if isinstance(self.model_retries, bool):
msg = f"model_retries must be an int, got {self.model_retries!r}"
raise TypeError(msg)
if self.model_retries < 0:
msg = f"model_retries must be >= 0, got {self.model_retries}"
raise ValueError(msg)
if isinstance(self.cli_max_retries, bool):
msg = (
f"cli_max_retries must be None or an int, got {self.cli_max_retries!r}"
)
raise TypeError(msg)
if self.cli_max_retries is not None and self.cli_max_retries < 0:
msg = f"cli_max_retries must be >= 0, got {self.cli_max_retries}"
raise ValueError(msg)
def apply_to_runtime_state(self) -> None:
"""Commit this result's metadata to global `runtime_state`."""
state = _get_runtime_state()
state.model_name = self.model_name
state.model_provider = self.provider
state.model_context_limit = self.context_limit
state.model_unsupported_modalities = self.unsupported_modalities
def _apply_profile_overrides(
model: BaseChatModel,
overrides: dict[str, Any],
model_name: str,
*,View on GitHub (pinned to a1af029e6e)
Solutions
- Pass an int or None for `cli_max_retries`, never a bool.
- Coerce config-sourced values with a validator that rejects bools before construction.
- Use None to mean 'flag not set' rather than False.
Example fix
// before ModelResult(..., cli_max_retries=False) // after ModelResult(..., cli_max_retries=None) # or an int like 3
Defensive patterns
Strategy: type-guard
Validate before calling
def is_cli_max_retries(v: object) -> bool:
return v is None or (isinstance(v, int) and not isinstance(v, bool) and v >= 0)
assert is_cli_max_retries(cli_max_retries) Type guard
def is_optional_int(v: object) -> TypeGuard[int | None]:
return v is None or (isinstance(v, int) and not isinstance(v, bool)) Try / catch
try:
result = ModelResult(..., cli_max_retries=v)
except TypeError:
result = ModelResult(..., cli_max_retries=None if isinstance(v, bool) else v) Prevention
- Use None (not False) for 'flag not set'
- Coerce CLI/config values with a bool-rejecting validator before plumbing them into ModelResult
- Let argparse's non_negative_int own the flag parsing; don't re-derive the value as a bool
When it happens
Trigger: Constructing `ModelResult(...)` with `cli_max_retries=True`/`False`. The CLI flag path enforces `non_negative_int`, so this fires only when the value bypasses argparse (programmatic construction, hand-wired config plumbing).
Common situations: Tests or tooling constructing ModelResult directly; a bool leaking from a config parser that accepts true/false.
Related errors
- model_retries must be an int, got {self.model_retries!r}
- interpreter_ptc must be False, 'safe', 'all', or a list of t
- model_retries must be >= 0, got {self.model_retries}
- cli_max_retries must be >= 0, got {self.cli_max_retries}
- Goal criteria request must be an object.
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/b07961832ac11109.
Report an issue: GitHub.