{"record":{"id":"4e4c20ef0e02e283","repo":"zylon-ai/private-gpt","slug":"header-and-content-length-mismatch-len-value-hea","errorCode":null,"errorMessage":"Header and content length mismatch: {len(value.header)} != {len(value.content)}","messagePattern":"Header and content length mismatch: (.+?) != (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/readers/nodes/table_node.py","lineNumber":182,"sourceCode":"    ) -> dict[str, Any]:\n        encoder = NpEncoder()\n        d = super().model_dump(\n            include_parent=include_parent, include_children=include_children, **kwargs\n        )\n        d[\"content\"] = encoder.encode(d[\"content\"])\n        return d\n\n    @classmethod\n    def from_dict(cls, data: builtins.dict[str, Any], **kwargs: Any) -> Self:\n        encoder = NpEncoder()\n        data[\"content\"] = encoder.decode(data[\"content\"])\n        return super().from_dict(data, **kwargs)\n\n    def set_content(self, value: Any) -> None:\n        if not isinstance(value, TableRowNode.Meta):\n            raise ValueError(f\"Expected TableRowNode.Meta, got {type(value)}\")\n        if len(value.header) != len(value.content):\n            raise ValueError(\n                f\"Header and content length mismatch: {len(value.header)} != {len(value.content)}\"\n            )\n\n        # Store content\n        self.header = value.header\n        self.content = value.content\n\n    def is_first_row(self) -> bool:\n        if not self.parent:\n            return False\n\n        siblings = self.parent.children\n        if not siblings:\n            return False\n\n        # Validate idx - defensive check for partial loading\n        current_index = self.idx if 0 <= self.idx < len(siblings) else None\n        if current_index is not None and siblings[current_index] is not self:","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/readers/nodes/table_node.py#L164-L200","documentation":"TableRowNode.set_content validates that the header list and the content (row values) list have identical length before storing them; a mismatch means the table row node would be internally inconsistent (each column needs exactly one value). It raises ValueError with both lengths so you can immediately see the discrepancy. This is a data-shape error at node construction time, usually caused by upstream parsing producing ragged rows.","triggerScenarios":"Calling TableRowNode.set_content(value) where value is a TableRowNode.Meta whose len(value.header) != len(value.content) — e.g. a parsed CSV row with fewer/more fields than the header, or manually building a Meta with mismatched lists.","commonSituations":"Ingesting malformed delimited files (ragged CSV/TSV rows); a delimiter reader that splits on an unexpected delimiter; schema drift where a column was added/removed mid-file; hand-constructed TableRowNode.Meta in tests or custom readers.","solutions":["Log the header and content lists before calling set_content and fix the upstream parser so every row has exactly len(header) values (pad with empty strings or drop malformed rows).","If rows legitimately vary, normalize them first: `row = row[:len(header)] + [''] * (len(header) - len(row))`.","Enable skip/preprocess options on the delimiter reader (e.g. pandas on_bad_lines handling) so ragged rows never reach node construction.","If building Meta manually, assert lengths match before assignment."],"exampleFix":"# before\nmeta = TableRowNode.Meta(header=[\"a\", \"b\", \"c\"], content=[\"1\", \"2\"])\nnode.set_content(meta)  # ValueError: mismatch 3 != 2\n\n# after\nrow = [\"1\", \"2\"]\nrow = row[:3] + [\"\"] * (3 - len(row))\nmeta = TableRowNode.Meta(header=[\"a\", \"b\", \"c\"], content=row)\nnode.set_content(meta)","handlingStrategy":"validation","validationCode":"def make_row_meta(header: list[str], content: list[Any]) -> TableRowNode.Meta | None:\n    if len(header) != len(content):\n        logger.warning(\"Dropping ragged row: %d header vs %d values\", len(header), len(content))\n        return None\n    return TableRowNode.Meta(header=header, content=content)","typeGuard":"def is_valid_table_row(value: Any) -> bool:\n    return (\n        isinstance(value, TableRowNode.Meta)\n        and isinstance(value.header, list)\n        and isinstance(value.content, list)\n        and len(value.header) == len(value.content)\n    )","tryCatchPattern":"try:\n    node.set_content(meta)\nexcept ValueError as e:\n    logger.warning(\"Rejected malformed row: %s\", e)\n    # skip this row, keep ingesting the rest","preventionTips":["Normalize every parsed row to len(header) before building nodes.","Configure the delimiter reader to skip/pad bad lines instead of failing node construction.","Assert header/content lengths in unit tests for custom table parsers."],"tags":["validation","table","ingestion","data-shape","csv"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}