HKUDS/Vibe-Trading · error · ValueError
instrument_id is required and cannot be empty
Error message
instrument_id is required and cannot be empty
What it means
Instrument.__post_init__ requires a non-empty instrument_id after stripping. If instrument_id is not a str (or is whitespace-only), cleaned becomes '' and the constructor raises, because an instrument cannot be identified without an id.
Source
Thrown at agent/src/entities/models.py:214
instrument_id: str
currency: str
name: str = ""
issuer: Entity | None = None
inception_date: date | None = None
def __post_init__(self) -> None:
"""Validate the identifier and normalize currency and inception date.
Raises:
ValueError: If ``instrument_id`` is blank, the currency is invalid,
or ``inception_date`` is not a supported date value.
"""
cleaned = (
self.instrument_id.strip() if isinstance(self.instrument_id, str) else ""
)
if not cleaned:
raise ValueError("instrument_id is required and cannot be empty")
object.__setattr__(self, "instrument_id", cleaned)
object.__setattr__(self, "currency", normalize_currency(self.currency))
object.__setattr__(self, "name", self.name.strip() if self.name else "")
if self.inception_date is not None:
object.__setattr__(
self,
"inception_date",
normalize_date(self.inception_date, field_name="inception_date"),
)
@dataclass(frozen=True)
class Security(Instrument):
"""A listed security identified by a ticker on a venue.
A ``Security`` here is the *reference* record only. Its price history still
belongs to the bar-based loader path; this class exists so a corporate
action or a dividend stream can be attached to a named instrument.View on GitHub (pinned to 80ffdda44c)
Solutions
- Check for a truthy, stripped id before constructing: row.get('symbol','').strip() and skip/log empty rows
- Fix data extraction so the id column is always a non-empty string
- Guard at ingest with a validation pass that reports which source rows lack ids
Example fix
# before
Instrument(instrument_id=row.get('ticker'), currency='USD')
# after
iid = (row.get('ticker') or '').strip()
if not iid:
continue # or log and skip
Instrument(instrument_id=iid, currency='USD') Defensive patterns
Strategy: validation
Validate before calling
iid = row.get('instrument_id')
if not isinstance(iid, str) or not iid.strip():
raise ValueError(f"row missing instrument_id: {row!r}")
inst = Instrument(instrument_id=iid, ...) Type guard
def has_instrument_id(row: dict) -> bool:
v = row.get('instrument_id')
return isinstance(v, str) and bool(v.strip()) Try / catch
try:
inst = Instrument(instrument_id=row['id'], ...)
except ValueError as exc:
if 'instrument_id' in str(exc):
log.warning('skipping row without instrument_id: %r', row)
continue
raise Prevention
- Make instrument_id a required column in ingest schemas
- Never default identifiers to empty strings or None placeholders
- Report row numbers of missing-id rows so sources can be fixed
When it happens
Trigger: Instrument(instrument_id=''), Instrument(instrument_id=' '), or passing a non-string (None, int) — the isinstance check yields an empty cleaned string. Also occurs when a dict key is missing and .get() returns None.
Common situations: Parsing spreadsheets/CSVs where the ticker/id column has blank cells; a dict built with a typo'd key so the id field gets None; rows with only whitespace or placeholder dashes in the symbol column.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- amount must be numeric, got {self.amount!r}
- unknown entity_type {self.entity_type!r}; expected one of: {
- entity {self.entity_id!r} cannot be its own parent
- unknown security_type {self.security_type!r}; expected one o
- unknown structure {self.structure!r}; expected one of: {vali
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/1d77226739c4eb3c.
Report an issue: GitHub.