HKUDS/Vibe-Trading · error · ValueError
management_fee_rate must be a decimal fraction in [0, 1] (0.
Error message
management_fee_rate must be a decimal fraction in [0, 1] (0.02 means 2%), got {self.management_fee_rate!r} What it means
Fund.__post_init__ validates management_fee_rate as a decimal fraction in [0, 1] — 0.02 means 2%. A rate outside that interval (typically 2.0 meaning 2%) is rejected to prevent hundred-fold fee errors.
Source
Thrown at agent/src/entities/models.py:322
raise ValueError(
f"unknown structure {self.structure!r}; expected one of: {valid}"
) from exc
if self.vintage_year is not None and not 1800 <= int(self.vintage_year) <= 2200:
raise ValueError(
f"vintage_year={self.vintage_year!r} is outside the plausible "
"range 1800-2200"
)
if self.commitment is not None:
if float(self.commitment) < 0:
raise ValueError(
f"commitment must be non-negative (it is a size, not a signed "
f"cash flow), got {self.commitment!r}"
)
object.__setattr__(self, "commitment", float(self.commitment))
if self.management_fee_rate is not None:
rate = float(self.management_fee_rate)
if not 0.0 <= rate <= 1.0:
raise ValueError(
f"management_fee_rate must be a decimal fraction in [0, 1] "
f"(0.02 means 2%), got {self.management_fee_rate!r}"
)
object.__setattr__(self, "management_fee_rate", rate)
@dataclass(frozen=True)
class Bond(Instrument):
"""A debt instrument paying scheduled coupons and returning principal.
Attributes:
face_value: Redemption amount per unit, in ``currency``. Positive.
coupon_rate: Annual coupon as a decimal fraction (``0.05`` means 5%),
not a percentage. Zero marks a zero-coupon bond.
coupon_frequency: Coupon payments per year. Zero is only valid for a
zero-coupon bond.
maturity_date: Redemption date, when known.
day_count: Day-count convention label, e.g. ``"30/360"`` orView on GitHub (pinned to 80ffdda44c)
Solutions
- Divide percentages by 100 before passing: 2% -> 0.02
- If the value is in basis points, divide by 10_000
- Add a UI/ingest conversion step so the model always receives the decimal fraction
Example fix
# before Fund(instrument_id='f1', management_fee_rate=2.0) # meant 2% # after Fund(instrument_id='f1', management_fee_rate=0.02)
Defensive patterns
Strategy: validation
Validate before calling
rate = row.get('management_fee_rate')
if rate is not None:
rate = float(rate)
if rate > 1.0:
rate /= 100.0 # percent -> fraction
Fund(..., management_fee_rate=rate) Type guard
def is_valid_fee_rate(r) -> bool:
return r is None or 0.0 <= float(r) <= 1.0 Prevention
- Agree on a fraction convention across UI, API, and storage
- Convert percent/bps inputs at the system boundary
- Document 0.02 = 2% wherever fees are configured
When it happens
Trigger: Fund(..., management_fee_rate=2.0) (percentage instead of fraction), management_fee_rate=150 (basis points), or a negative rate. Values like 0.02 pass; 2 fails only if >1.0, negatives fail the lower bound.
Common situations: User input or vendor data expressing fees in percent; basis-point values (200 bp) passed raw; mixing conventions between a UI showing '2%' and the model expecting 0.02.
Related errors
- coupon_rate must be a decimal fraction (0.05 means 5%), got
- unknown structure {self.structure!r}; expected one of: {vali
- vintage_year={self.vintage_year!r} is outside the plausible
- commitment must be non-negative (it is a size, not a signed
- coupon_rate cannot be negative, got {rate!r}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/cf5285a5de8f1016.
Report an issue: GitHub.