langchain-ai/deepagents · error · ValueError
{name} must be a positive finite number, got {budget!r}
Error message
{name} must be a positive finite number, got {budget!r} What it means
`AutoModeHITLMiddleware.__init__` validates the review-deadline budgets (e.g. `classifier_construction_timeout_seconds`) as a security control: a zero, negative, NaN, or infinite timeout would expire immediately and silently turn Auto mode into 'deny every gated batch, then escalate'. Any budget value that is not a positive finite number raises this ValueError at the boundary.
Source
Thrown at libs/code/deepagents_code/auto_mode.py:2184
):
msg = "trusted_compaction_tool must be named compact_conversation"
raise ValueError(msg)
# The review deadline is a security control's budget, so reject a
# nonsensical one at the boundary rather than trusting every caller:
# a zero, negative, or NaN timeout expires immediately, silently turning
# Auto into "deny every gated batch, then escalate". Callers that read
# user config go through `resolve_auto_classifier_timeout`, which bounds
# the value; this guards programmatic construction.
for name, budget in (
("classifier_timeout_seconds", classifier_timeout_seconds),
(
"classifier_construction_timeout_seconds",
classifier_construction_timeout_seconds,
),
):
if not math.isfinite(budget) or budget <= 0:
msg = f"{name} must be a positive finite number, got {budget!r}"
raise ValueError(msg)
interrupt_map = dict(interrupt_on)
interrupt_map["create_temp_artifact"] = {
"allowed_decisions": ["approve", "reject"],
"description": "Create an exclusively allocated OS-temp scratch file.",
}
interrupt_map["delete_temp_artifact"] = {
"allowed_decisions": ["approve", "reject"],
"description": "Delete an exact current-request OS-temp scratch file.",
}
super().__init__(interrupt_map)
self._worktree_root = Path(worktree_root).resolve(strict=False)
from deepagents_code._git import read_git_remote_url_from_filesystem
origin = read_git_remote_url_from_filesystem(self._worktree_root) or ""
self._trusted_environment = {
"worktree_root": str(self._worktree_root),
"origin_remote": _redact_remote(origin),
}View on GitHub (pinned to a1af029e6e)
Solutions
- Route user config through `resolve_auto_classifier_timeout`, which clamps the value to a valid positive bound.
- Pass a positive finite float/int, e.g. 30 (seconds), for every budget parameter.
- Sanitize loaded config: reject or replace 0/negative/NaN/inf values before constructing the middleware.
Example fix
// before
mw = AutoModeHITLMiddleware(classifier_construction_timeout_seconds=0) # config default meaning 'unset'
// after
budget = resolve_auto_classifier_timeout(config.get('classifier_timeout')) # bounds the value
mw = AutoModeHITLMiddleware(classifier_construction_timeout_seconds=budget) Defensive patterns
Strategy: validation
Validate before calling
import math
for name, budget in [('classifier_construction_timeout_seconds', cfg.get('classifier_construction_timeout_seconds'))]:
if budget is not None and (not math.isfinite(budget) or budget <= 0):
raise ValueError(f'{name} invalid: {budget!r}') Type guard
def is_valid_budget(value: object) -> bool:
return isinstance(value, (int, float)) and not isinstance(value, bool) and math.isfinite(value) and value > 0 Try / catch
try:
mw = AutoModeHITLMiddleware(classifier_construction_timeout_seconds=budget)
except ValueError as e:
if 'must be a positive finite number' in str(e):
budget = resolve_auto_classifier_timeout(None) # fall back to bounded default
mw = AutoModeHITLMiddleware(classifier_construction_timeout_seconds=budget)
else:
raise Prevention
- Always construct budgets via `resolve_auto_classifier_timeout` instead of passing raw config values.
- Reject 0/negative/NaN/inf at config-load time with a clear error of your own.
- Remember that 0 usually means 'unset' elsewhere but is invalid here — map unset to None or a positive default.
- Add a unit test that feeds NaN and 0 to config parsing.
When it happens
Trigger: Passing `classifier_construction_timeout_seconds=0`, a negative number, `float('nan')`, or `float('inf')` (or the same for other budget parameters in the checked list) to `AutoModeHITLMiddleware.__init__`.
Common situations: Loading a timeout from config where 0 means 'no timeout' in another library; YAML/JSON config containing null/NaN; computing a deadline from a clock skew or subtraction that yields a non-positive value; programmatic construction bypassing `resolve_auto_classifier_timeout`, which normally bounds the value.
Related errors
- {what} must be absolute: {path}
- Home directory is not absolute: {launch_home}. Set $HOME to
- Invalid {SERVER_ENV_PREFIX}ALLOW_FS_TOOLS value: unknown fil
- Invalid {SERVER_ENV_PREFIX}ALLOW_FS_TOOLS value: {raw!r}; ex
- shell_allow_list must be None or non-empty
AI-assisted analysis of langchain-ai/deepagents@a1af029e6e (2026-08-29).
Data as JSON: /api/errors/2a4ef53ff97d5b45.
Report an issue: GitHub.