{"record":{"id":"03d7944b39e32a25","repo":"HKUDS/Vibe-Trading","slug":"cashflowseries-members-must-be-cashflow-got-type","errorCode":null,"errorMessage":"CashFlowSeries members must be CashFlow, got {type(item).__name__}","messagePattern":"CashFlowSeries members must be CashFlow, got (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/entities/cashflow.py","lineNumber":230,"sourceCode":"    \"\"\"\n\n    flows: tuple[CashFlow, ...] = ()\n    currency: str | None = None\n    pre_translated: bool = False\n\n    def __post_init__(self) -> None:\n        \"\"\"Validate membership and currency coherence, then order by date.\n\n        Raises:\n            ValueError: If a member is not a ``CashFlow``, or if\n                ``pre_translated`` is set without naming a reporting currency.\n            CurrencyMismatchError: If the flows span multiple currencies while\n                ``pre_translated`` is False, or contradict a declared currency.\n        \"\"\"\n        flows = tuple(self.flows)\n        for item in flows:\n            if not isinstance(item, CashFlow):\n                raise ValueError(\n                    f\"CashFlowSeries members must be CashFlow, got \"\n                    f\"{type(item).__name__}\"\n                )\n\n        declared = (\n            normalize_currency(self.currency) if self.currency is not None else None\n        )\n        present = {flow.currency for flow in flows}\n\n        if self.pre_translated:\n            if declared is None:\n                raise ValueError(\n                    \"pre_translated=True asserts the flows were already converted, \"\n                    \"so the reporting currency must be named explicitly via \"\n                    \"currency=...\"\n                )\n        else:\n            if len(present) > 1:","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/entities/cashflow.py#L212-L248","documentation":"CashFlowSeries is a homogeneous container: every element of flows must be a CashFlow instance. A non-CashFlow member (dict, tuple, subclass-less duck-typed object) fails with the offending type name before the series can normalize currency and sort by date.","triggerScenarios":"CashFlowSeries(flows=[{'amount': 100}, cashflow_instance]) or passing a list of raw dicts/tuples from a loader that never mapped them to entities.","commonSituations":"Forgetting to convert loaded rows to CashFlow objects; mixing entity types in a generic pipeline; a mock/stub object used in tests instead of the real dataclass.","solutions":["Map each row to CashFlow(...) before constructing the series","If mixing types intentionally, filter to CashFlow instances first"],"exampleFix":"# before\nCashFlowSeries(flows=raw_rows)  # list of dicts\n# after\nflows = [CashFlow(**r) for r in raw_rows]\nCashFlowSeries(flows=flows)","handlingStrategy":"type-guard","validationCode":"from agent.src.entities.cashflow import CashFlow\nflows = [f for f in candidate_flows if isinstance(f, CashFlow)]\nassert len(flows) == len(candidate_flows), 'non-CashFlow members present'","typeGuard":"from agent.src.entities.cashflow import CashFlow\ndef all_cashflows(seq) -> bool:\n    return all(isinstance(f, CashFlow) for f in seq)","tryCatchPattern":"try:\n    series = CashFlowSeries(flows=flows)\nexcept ValueError as e:\n    if 'must be CashFlow' in str(e):\n        flows = [CashFlow(**f) for f in flows if not isinstance(f, CashFlow)]","preventionTips":["Always materialize entities at the loader boundary","Type the pipeline variable as list[CashFlow] for static checks"],"tags":["python","cashflow","type-validation"],"backgroundTag":"container-type-validation","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}