HKUDS/Vibe-Trading · error · ValueError
kind={self.kind!r} must have a {direction} amount under the
Error message
kind={self.kind!r} must have a {direction} amount under the holder-perspective sign convention, got {amount!r}. Flip the sign, or use a distinct kind if this flow is genuinely two-directional (e.g. 'recallable_distribution'). What it means
Each CashFlow kind has a fixed sign direction (holder perspective), e.g. dividends are cash in (positive) and purchases are cash out (negative). If the amount's sign contradicts KIND_DIRECTION for that kind, the entity refuses construction rather than silently misreporting direction.
Source
Thrown at agent/src/entities/cashflow.py:173
try:
amount = float(self.amount)
except (TypeError, ValueError) as exc:
raise ValueError(
f"amount must be numeric, got {self.amount!r}"
) from exc
if not math.isfinite(amount):
raise ValueError(
f"amount must be a finite number, got {self.amount!r}; a missing "
"value must be fixed at the source, not carried as NaN"
)
object.__setattr__(self, "amount", amount)
required_sign = KIND_DIRECTION.get(self.kind)
if required_sign is not None and amount != 0.0:
if (amount > 0) != (required_sign > 0):
direction = "positive (cash in)" if required_sign > 0 else "negative (cash out)"
raise ValueError(
f"kind={self.kind!r} must have a {direction} amount under the "
f"holder-perspective sign convention, got {amount!r}. Flip the "
"sign, or use a distinct kind if this flow is genuinely "
"two-directional (e.g. 'recallable_distribution')."
)
if not isinstance(self.metadata, Mapping):
raise ValueError(
f"metadata must be a mapping, got {type(self.metadata).__name__}"
)
object.__setattr__(self, "metadata", MappingProxyType(dict(self.metadata)))
@property
def is_valuation(self) -> bool:
"""Whether this record is a mark rather than a settled cash movement.
Returns:
True when ``kind`` is one of ``VALUATION_KINDS``.View on GitHub (pinned to 80ffdda44c)
Solutions
- Flip the amount's sign to match the kind's required direction (see the message text for which direction is expected)
- If the flow is genuinely two-directional (e.g. recallable distributions that can be clawed back), use a kind without a fixed direction such as 'recallable_distribution'
- Apply the sign at ingest: amount = abs(amount) * expected_sign based on the kind mapping
Example fix
# before CashFlow(date=d, kind='purchase', amount=1000.0, currency='USD') # after CashFlow(date=d, kind='purchase', amount=-1000.0, currency='USD')
Defensive patterns
Strategy: validation
Validate before calling
REQUIRED_SIGN = {'purchase': -1, 'dividend': 1} # mirror KIND_DIRECTION
row['amount'] = abs(float(row['amount'])) * REQUIRED_SIGN.get(row['kind'], 1) Try / catch
try:
CashFlow(...)
except ValueError as e:
if 'sign convention' in str(e):
row['amount'] = -row['amount'] # only if direction metadata is trusted Prevention
- Apply kind-based sign at ingest rather than trusting raw source signs
- Document the holder perspective in your ETL docs
- Add fixtures covering each kind's sign
When it happens
Trigger: CashFlow(kind='purchase', amount=1000.0) when purchase requires a negative amount, or CashFlow(kind='dividend', amount=-50.0) when dividend must be positive; amount 0.0 is always allowed.
Common situations: Feeding raw unsigned magnitudes from a brokerage CSV where direction lives in a separate column; mixing conventions (inflow-positive vs outflow-positive) between data sources; genuinely two-directional flows modeled with the wrong kind.
Related errors
- amount must be a finite number, got {self.amount!r}; a missi
- pre_translated=True asserts the flows were already converted
- start {lower} is after end {upper}
- flows[{index}]: {exc}
- flow_timing must be {FLOW_TIMING_END!r} or {FLOW_TIMING_STAR
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/0609d95900d330ca.
Report an issue: GitHub.