{"record":{"id":"1d77226739c4eb3c","repo":"HKUDS/Vibe-Trading","slug":"instrument-id-is-required-and-cannot-be-empty","errorCode":null,"errorMessage":"instrument_id is required and cannot be empty","messagePattern":"instrument_id is required and cannot be empty","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/entities/models.py","lineNumber":214,"sourceCode":"\n    instrument_id: str\n    currency: str\n    name: str = \"\"\n    issuer: Entity | None = None\n    inception_date: date | None = None\n\n    def __post_init__(self) -> None:\n        \"\"\"Validate the identifier and normalize currency and inception date.\n\n        Raises:\n            ValueError: If ``instrument_id`` is blank, the currency is invalid,\n                or ``inception_date`` is not a supported date value.\n        \"\"\"\n        cleaned = (\n            self.instrument_id.strip() if isinstance(self.instrument_id, str) else \"\"\n        )\n        if not cleaned:\n            raise ValueError(\"instrument_id is required and cannot be empty\")\n        object.__setattr__(self, \"instrument_id\", cleaned)\n        object.__setattr__(self, \"currency\", normalize_currency(self.currency))\n        object.__setattr__(self, \"name\", self.name.strip() if self.name else \"\")\n        if self.inception_date is not None:\n            object.__setattr__(\n                self,\n                \"inception_date\",\n                normalize_date(self.inception_date, field_name=\"inception_date\"),\n            )\n\n\n@dataclass(frozen=True)\nclass Security(Instrument):\n    \"\"\"A listed security identified by a ticker on a venue.\n\n    A ``Security`` here is the *reference* record only. Its price history still\n    belongs to the bar-based loader path; this class exists so a corporate\n    action or a dividend stream can be attached to a named instrument.","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/entities/models.py#L196-L232","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before\nInstrument(instrument_id=row.get('ticker'), currency='USD')\n\n# after\niid = (row.get('ticker') or '').strip()\nif not iid:\n    continue  # or log and skip\nInstrument(instrument_id=iid, currency='USD')","handlingStrategy":"validation","validationCode":"iid = row.get('instrument_id')\nif not isinstance(iid, str) or not iid.strip():\n    raise ValueError(f\"row missing instrument_id: {row!r}\")\ninst = Instrument(instrument_id=iid, ...)","typeGuard":"def has_instrument_id(row: dict) -> bool:\n    v = row.get('instrument_id')\n    return isinstance(v, str) and bool(v.strip())","tryCatchPattern":"try:\n    inst = Instrument(instrument_id=row['id'], ...)\nexcept ValueError as exc:\n    if 'instrument_id' in str(exc):\n        log.warning('skipping row without instrument_id: %r', row)\n        continue\n    raise","preventionTips":["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"],"tags":["python","dataclass","required-field","instruments"],"backgroundTag":"missing-required-field","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}