HKUDS/Vibe-Trading · error · ValuationError
{model}: {name} must be a number, got {value!r}
Error message
{model}: {name} must be a number, got {value!r} What it means
require_positive first coerces the value with float(); if that raises TypeError/ValueError (non-numeric input like a string or None), it raises this 'must be a number' ValuationError. Used for values meaningless at/below zero (growth rates, share counts, etc.) in __post_init__, equity_bridge, sensitivity_grid, project_three_statement.
Source
Thrown at agent/src/quantlib/valuation/contracts.py:155
def require_positive(value: float, name: str, model: str) -> float:
"""Check a value that is meaningless at or below zero.
Args:
value: The value to check, e.g. a share count or a discount rate.
name: Field name for the error message.
model: Model name for the error message.
Returns:
``value`` as a float.
Raises:
ValuationError: If the value is not a finite number greater than zero.
"""
try:
numeric = float(value)
except (TypeError, ValueError) as exc:
raise ValuationError(f"{model}: {name} must be a number, got {value!r}") from exc
if not numeric > 0.0 or numeric != numeric or numeric in (float("inf"), float("-inf")):
raise ValuationError(
f"{model}: {name} must be a finite positive number, got {numeric}"
)
return numeric
View on GitHub (pinned to 80ffdda44c)
Solutions
- Convert to float explicitly at your boundary and fail with your own clearer message.
- Strip '%' and other decorations before parsing if your config uses formatted numbers.
- Use typed config (pydantic/dataclass with float fields) so strings never reach the library.
Example fix
# before shares = row['shares'] # '1.2B' # after shares = parse_shares(row['shares']) # returns 1_200_000_000.0, raises on 'n/a'
Defensive patterns
Strategy: type-guard
Validate before calling
try:
value = float(value)
except (TypeError, ValueError):
raise ValueError(f'expected a number, got {value!r}') Type guard
def is_numeric(v):
return isinstance(v, (int, float)) and not isinstance(v, bool) Try / catch
except ValuationError as e:
if 'must be a number' in str(e):
value = parse_formatted(row[name]) # your parser Prevention
- Parse formatted strings ('5%') at the config boundary
- Use typed config objects so strings never reach model APIs
When it happens
Trigger: Passing '5%', None, a dict, or an unparseable string where a positive float is required, e.g. a shares figure of 'n/a'.
Common situations: Config values left as strings ('0.05' parses, '5%' does not); Excel/CSV cells with text like 'n/a'; None defaults leaking into required parameters.
Related errors
- {model}: {name} must be a number, got {value!r}
- {field_name} must be a string, got {type(value).__name__}
- {field_name} must be a date, datetime, or ISO-8601 string, g
- {model}: name is required and cannot be blank, got {name!r}
- {model}: eps_basis must be one of {EPS_BASES}, got {eps_basi
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/72667494258a1656.
Report an issue: GitHub.