HKUDS/Vibe-Trading · error · ValueError
kind must be a string, got {type(value).__name__}
Error message
kind must be a string, got {type(value).__name__} What it means
Raised by CashFlow normalize_kind when the kind argument is not a str instance (e.g. int, None, bytes). The kind label is normalized (lowercased, hyphens/spaces to underscores) and stored as a dataclass field, so non-string input fails fast in __post_init__ or the filter/external_flows helpers.
Source
Thrown at agent/src/entities/cashflow.py:112
def normalize_kind(value: str) -> str:
"""Normalize a cash-flow kind label to its canonical snake_case form.
Real files spell the same concept as ``"Capital Call"``, ``"capital-call"``,
or ``"CAPITAL_CALL"``. Normalizing means the sign check in ``KIND_DIRECTION``
actually bites on those files instead of silently treating each spelling as
an unconstrained custom kind.
Args:
value: Raw kind label from a caller or a file.
Returns:
Lower-cased label with spaces and hyphens collapsed to underscores.
Raises:
ValueError: If the label is not a string or is blank.
"""
if not isinstance(value, str):
raise ValueError(f"kind must be a string, got {type(value).__name__}")
cleaned = value.strip().lower().replace("-", "_").replace(" ", "_")
while "__" in cleaned:
cleaned = cleaned.replace("__", "_")
if not cleaned:
raise ValueError("kind is required and cannot be empty")
return cleaned
@dataclass(frozen=True)
class CashFlow:
"""A single dated cash amount in one currency.
Attributes:
date: Settlement date. ``datetime`` and ISO-8601 strings are accepted
and normalized to ``datetime.date``.
amount: Signed amount, positive into the holder. See the module
docstring for the convention and its enforcement.
kind: Canonical kind label, e.g. ``"capital_call"`` or ``"coupon"``.View on GitHub (pinned to 80ffdda44c)
Solutions
- Coerce kind to str before constructing: kind=str(value) if appropriate.
- Validate upstream data shapes (e.g. JSON schema) so kind is always a string.
- Check for None from optional mappings and supply a default label.
Example fix
# before normalize_kind(123) # after normalize_kind(str(123))
Defensive patterns
Strategy: type-guard
Validate before calling
def kind_is_str(value) -> bool:
return isinstance(value, str) Type guard
def is_kind_string(value) -> bool:
return isinstance(value, str) Try / catch
try:
flow = CashFlow(kind=raw_kind, ...)
except ValueError as e:
if 'kind must be a string' in str(e):
raise TypeError(f'kind must come from string fields, got {raw_kind!r}') from e
raise Prevention
- Validate incoming records with a schema (pydantic/jsonschema) before entity construction
- Coerce numeric labels to str explicitly at ingestion
When it happens
Trigger: Constructing a CashFlow-like entity or calling filter/external_flows with kind=42, kind=None, or bytes from un-decoded JSON input.
Common situations: Feeding raw JSON/YAML values where kind came back as a number or null; dynamic dicts built from spreadsheets where the column parses as int.
Related errors
- kind is required and cannot be empty
- amount must be numeric, got {self.amount!r}
- metadata must be a mapping, got {type(self.metadata).__name_
- CashFlowSeries members must be CashFlow, got {type(item).__n
- flows must contain CashFlow, got {type(flow).__name__}
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/8a66ba47fa0e4713.
Report an issue: GitHub.