HKUDS/Vibe-Trading · error · ValueError
coupon_frequency cannot be negative, got {self.coupon_freque
Error message
coupon_frequency cannot be negative, got {self.coupon_frequency!r} What it means
Bond.__post_init__ coerces coupon_frequency with int() and rejects negative values. Frequency is coupons per year (e.g. 2 for semi-annual); 0 is a valid sentinel meaning zero-coupon, but negative counts are invalid.
Source
Thrown at agent/src/entities/models.py:377
if self.face_value is not None:
face = float(self.face_value)
if face <= 0:
raise ValueError(f"face_value must be positive, got {self.face_value!r}")
object.__setattr__(self, "face_value", face)
if self.coupon_rate is not None:
rate = float(self.coupon_rate)
if rate < 0:
raise ValueError(f"coupon_rate cannot be negative, got {rate!r}")
if rate > 1.0:
raise ValueError(
f"coupon_rate must be a decimal fraction (0.05 means 5%), "
f"got {rate!r}; a value above 1.0 is almost certainly a "
"percentage"
)
object.__setattr__(self, "coupon_rate", rate)
frequency = int(self.coupon_frequency)
if frequency < 0:
raise ValueError(
f"coupon_frequency cannot be negative, got {self.coupon_frequency!r}"
)
if self.coupon_rate and frequency == 0:
raise ValueError(
f"coupon_frequency=0 marks a zero-coupon bond, but coupon_rate="
f"{self.coupon_rate!r} is non-zero"
)
object.__setattr__(self, "coupon_frequency", frequency)
if self.maturity_date is not None:
object.__setattr__(
self,
"maturity_date",
normalize_date(self.maturity_date, field_name="maturity_date"),
)
if self.inception_date is not None and self.maturity_date < self.inception_date:
raise ValueError(
f"maturity_date {self.maturity_date} precedes inception_date "
f"{self.inception_date}"View on GitHub (pinned to 80ffdda44c)
Solutions
- Pass a non-negative integer frequency (0 for zero-coupon, 1 annual, 2 semi-annual, 4 quarterly)
- Use None or a proper optional field for unknown frequency rather than -1
- Validate the frequency column at ingest against {0,1,2,12,...}
Example fix
# before Bond(instrument_id='b1', coupon_rate=0.05, coupon_frequency=-1) # after Bond(instrument_id='b1', coupon_rate=0.05, coupon_frequency=2)
Defensive patterns
Strategy: validation
Validate before calling
freq = int(row['coupon_frequency'])
if freq < 0:
raise ValueError(f'negative coupon_frequency {freq} on row {row_id}')
Bond(..., coupon_frequency=freq) Type guard
def is_valid_frequency(f) -> bool:
return f is None or int(f) >= 0 Prevention
- Use None for unknown frequencies instead of -1 sentinels
- Whitelist common frequencies: 0, 1, 2, 4, 12
When it happens
Trigger: Bond(..., coupon_frequency=-1) or -2, or a negative value arising from arithmetic (e.g. subtracting a default frequency). Floats like 2.0 are int()-truncated to 2 and accepted.
Common situations: Misparsed spreadsheet columns with minus signs; intermediate calculations that compute frequency as a difference; sentinel values like -1 for 'unknown' leaking into the field.
Related errors
- face_value must be positive, got {self.face_value!r}
- coupon_rate cannot be negative, got {rate!r}
- coupon_rate must be a decimal fraction (0.05 means 5%), got
- coupon_frequency=0 marks a zero-coupon bond, but coupon_rate
- maturity_date {self.maturity_date} precedes inception_date {
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/fef2e172191f7fbe.
Report an issue: GitHub.