HKUDS/Vibe-Trading · error · ValuationError
{MODEL_NAME}: max_circularity_iterations must be >= 1, got {
Error message
{MODEL_NAME}: max_circularity_iterations must be >= 1, got {max_circularity_iterations!r} What it means
project_three_statement validates solver settings up front: max_circularity_iterations must be an integer >= 1. Zero or negative values (or a float like 0) raise ValuationError immediately, since the circularity loop would otherwise never execute.
Source
Thrown at agent/src/quantlib/valuation/threestatement.py:710
Raises:
MissingInputError: If ``opening`` or ``drivers`` is missing a required
field.
ValuationError: If the driver sequences disagree in length, are empty,
if any opening or driver value is not a finite number, or if
``circularity_tolerance`` / ``balance_tolerance`` /
``max_circularity_iterations`` are not usable.
BalanceSheetError: If the opening balance sheet, or any projected
period's balance sheet, does not balance.
ConvergenceError: If any period's interest/revolver circularity fails
to converge within ``max_circularity_iterations``.
"""
require_inputs(opening, OPENING_REQUIRED_FIELDS, MODEL_NAME)
require_inputs(drivers, DRIVER_REQUIRED_FIELDS, MODEL_NAME)
circularity_tolerance = require_positive(circularity_tolerance, "circularity_tolerance", MODEL_NAME)
balance_tolerance = require_positive(balance_tolerance, "balance_tolerance", MODEL_NAME)
if max_circularity_iterations < 1:
raise ValuationError(
f"{MODEL_NAME}: max_circularity_iterations must be >= 1, got "
f"{max_circularity_iterations!r}"
)
for field in OPENING_REQUIRED_FIELDS:
_require_finite(opening[field], f"opening {field}", MODEL_NAME)
for field in DRIVER_REQUIRED_FIELDS:
for index, raw in enumerate(drivers[field]):
_require_finite(raw, f"drivers {field}[{index}]", MODEL_NAME)
periods = _resolve_period_count(drivers)
opening_balance_sheet = BalanceSheet(
period=0,
cash=float(opening["cash"]),
net_working_capital=float(opening["net_working_capital"]),
ppe=float(opening["ppe"]),
revolver_balance=float(opening["revolver_balance"]),View on GitHub (pinned to 80ffdda44c)
Solutions
- Set max_circularity_iterations to at least 1 (practically 50-1000).
- Fix the config default for the missing key.
- Validate the setting before the call if it comes from user input.
Example fix
# before project_three_statement(opening, drivers, max_circularity_iterations=0) # after project_three_statement(opening, drivers, max_circularity_iterations=100)
Defensive patterns
Strategy: validation
Validate before calling
assert isinstance(max_circularity_iterations, int) and max_circularity_iterations >= 1
Type guard
def valid_iterations(n) -> bool:
return isinstance(n, int) and n >= 1 Try / catch
except ValuationError as e:
if 'max_circularity_iterations' in str(e): reset_to_default() Prevention
- Give config knobs explicit safe defaults
- Validate solver settings alongside financial inputs
When it happens
Trigger: Passing max_circularity_iterations=0, a negative number, or a config default that was never set and defaulted to 0; also passing a float such as 50.0 can slip through only if comparisons hold, so integers < 1 are the real trigger.
Common situations: Config files where the knob is optional and omitted-then-zeroed; programmatic sweeps that include 0; disabling iterations intentionally but using the wrong API.
Related errors
- {model}: {name} must be a number, got {value!r}
- max_bytes must be positive, got {max_bytes}
- run_dcf: capital_structure_basis must be one of {CAPITAL_STR
- BalanceSheetError(balance_sheet.period, assets, liabilities,
- {model}: {name} must be a finite number, got {numeric!r}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/b016f47f21669328.
Report an issue: GitHub.