NousResearch/hermes-agent · error · ValueError
Anthropic Messages adapter requires a positive max_tokens va
Error message
Anthropic Messages adapter requires a positive max_tokens value for model {model!r}; got {requested!r} and no model default resolved. What it means
The Anthropic Messages adapter requires a positive max_tokens on every call. This ValueError fires when the caller passed a non-positive value (0/None/negative) AND _get_anthropic_max_output(model) resolved no positive default for that model name. The resolver deliberately does no context-window clamping so the positive-value contract stays independent of endpoint specifics.
Source
Thrown at agent/anthropic_adapter.py:258
Prefers ``requested`` when it is a positive finite number; otherwise
falls back to the model's output ceiling. Raises ``ValueError`` if no
positive budget can be resolved (should not happen with current model
table defaults, but guards against a future regression where
``_get_anthropic_max_output`` could return ``0``).
Separately, callers apply a context-window clamp — this resolver does
not, to keep the positive-value contract independent of endpoint
specifics.
Ported from openclaw/openclaw#66664 (resolveAnthropicMessagesMaxTokens).
"""
resolved = _resolve_positive_anthropic_max_tokens(requested)
if resolved is not None:
return resolved
fallback = _get_anthropic_max_output(model)
if fallback > 0:
return fallback
raise ValueError(
f"Anthropic Messages adapter requires a positive max_tokens value for "
f"model {model!r}; got {requested!r} and no model default resolved."
)
def _supports_adaptive_thinking(model: str) -> bool:
"""Return True for Claude models that use adaptive thinking (4.6+).
Defaults *unknown* Claude models to adaptive (the modern contract) and
only returns False for the explicit legacy list of older Claude families
that require manual budget-based thinking. Non-Claude Anthropic-Messages
models (minimax, qwen3, …) return False so they keep the manual path.
Kimi / Moonshot models are the exception: their Anthropic-compatible
endpoints implement the adaptive contract (``thinking.type="adaptive"``
+ ``output_config.effort``, including ``xhigh`` and ``display``).
"""
if _model_name_is_kimi_family(model):View on GitHub (pinned to c896c09c42)
Solutions
- Pass an explicit positive max_tokens (e.g. 16384) at the call site
- If 'use the model default' was intended, omit the value entirely rather than zeroing it
- Add or update the model's default in the max-output resolution table so the fallback is positive
- Upgrade to a release where the new model's default is catalogued
Example fix
# before build_anthropic_request(messages=msgs, max_tokens=0) # after build_anthropic_request(messages=msgs, max_tokens=16384)
Defensive patterns
Strategy: validation
Validate before calling
def valid_max_tokens(value) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and value > 0
if max_tokens is not None:
assert valid_max_tokens(max_tokens), (
f"Anthropic Messages requires positive max_tokens, got {max_tokens!r}"
) Type guard
from typing import Any
def is_positive_int(value: Any) -> bool:
"""Narrows to a positive, non-bool integer usable as Anthropic max_tokens."""
return isinstance(value, int) and not isinstance(value, bool) and value > 0 Try / catch
try:
payload = build_anthropic_messages_request(messages, max_tokens=max_tokens)
except ValueError as e:
if "positive max_tokens" in str(e):
payload = build_anthropic_messages_request(messages, max_tokens=16384)
else:
raise Prevention
- Never pass 0/None as 'unlimited' to the Anthropic Messages API — omit the value instead
- Keep the max-output default table updated when adopting new Claude model names
- Unit-test request builders with max_tokens in {None, 0, -1} to catch regressions early
When it happens
Trigger: Building/converting an Anthropic Messages request with max_tokens=0, None, or a negative number for a model that has no entry in the max-output table, so the fallback returns 0.
Common situations: A new or renamed Claude model not yet present in _get_anthropic_max_output's table while call-site code passes 0 meaning 'unlimited'; config sets max_tokens: 0 expecting a provider default; a caller copying chat-completions semantics where 0 can mean unset.
Related errors
- Preview mode — launching is disabled.
- no install root
- ${isPosix ? 'install.sh --manifest' : 'install.ps1 -Manifest
- Remote connection is not ready yet. Try again in a moment.
- Remote gateway URL is required.
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/79a435b8ece5f916.
Report an issue: GitHub.