HKUDS/Vibe-Trading · error · ValueError

{field} must be a positive integer, got {value!r}

Error message

{field} must be a positive integer, got {value!r}

What it means

Raised by qveris_tool._positive_int when an optional numeric parameter cannot be interpreted as a positive integer: the value fails float() conversion (TypeError/ValueError/OverflowError), is non-finite (NaN/inf), is not a whole number, or is < 1. Note that None and empty string are allowed and return the default, so only genuinely present-but-invalid values raise.

Source

Thrown at agent/src/tools/qveris_tool.py:376

    Args:
        value: Raw argument value; ``None`` and ``""`` mean "not supplied".
        field: Argument name, used in the error message.
        default: Value to use when the argument was not supplied.

    Returns:
        The requested integer, or ``default`` when the argument was absent.

    Raises:
        ValueError: If the value is present but not a finite positive integer.
            QVeris calls are billable, so an explicitly malformed option is
            rejected instead of being replaced by a default.
    """
    if value is None or value == "":
        return default
    try:
        number = float(value)
    except (TypeError, ValueError, OverflowError):
        raise ValueError(f"{field} must be a positive integer, got {value!r}") from None
    if not math.isfinite(number) or number != int(number) or int(number) < 1:
        raise ValueError(f"{field} must be a positive integer, got {value!r}")
    return int(number)


class _QVerisBaseTool(BaseTool):
    """Shared availability and client helpers for QVeris tools."""

    @classmethod
    def check_available(cls) -> bool:
        """Hide QVeris tools until explicitly enabled and keyed."""
        return is_qveris_configured()

    def _client(self) -> QVerisClient:
        return QVerisClient()


class QVerisSearchTool(_QVerisBaseTool):

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Pass a whole number >= 1 (or its string form like '50'), or omit/empty the parameter to use the default
  2. Coerce or validate numeric inputs before calling: check isdigit/whole-value and range
  3. Map 'unlimited' intents to a large explicit integer instead of 0
  4. Reject placeholder strings like 'null'/'nan'/'inf' in upstream input parsing

Example fix

# before
limit=0

# after
limit=100  # or omit limit to use the tool default
Defensive patterns

Strategy: validation

Validate before calling

def to_positive_int(value, field: str, default: int | None = None):
    if value is None or value == "":
        return default
    try:
        n = float(value)
    except (TypeError, ValueError, OverflowError):
        raise ValueError(f"{field} must be a positive integer, got {value!r}")
    if not math.isfinite(n) or n != int(n) or int(n) < 1:
        raise ValueError(f"{field} must be a positive integer, got {value!r}")
    return int(n)

limit = to_positive_int(raw_limit, "limit", default=25)

Type guard

def is_positive_int_value(v: object) -> bool:
    if isinstance(v, bool) or not isinstance(v, (int, float, str)):
        return False
    try:
        n = float(v)
    except (TypeError, ValueError, OverflowError):
        return False
    return math.isfinite(n) and n == int(n) and int(n) >= 1

Try / catch

try:
    result = tool.execute(limit=raw_limit, ...)
except ValueError as e:
    if "positive integer" in str(e):
        result = tool.execute(limit=None, ...)  # fall back to default and warn user

Prevention

When it happens

Trigger: Passing limit='abc' or limit=None-like strings such as 'null'/'nan' (float('nan') parses but fails isfinite); limit=2.5 (not whole); limit=0 or negative; limit=float('inf') via 'inf'; passing a dict/list that float() rejects with TypeError.

Common situations: LLM tool calls emitting stringified booleans or nulls ('true', 'null'); users passing decimal page sizes; config defaults of 0 meaning 'unlimited' but the tool requires >=1; untrusted numeric input from spreadsheets.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/f3ee0bc3e42b82d1. Report an issue: GitHub.