{"record":{"id":"69cff3495f05ce73","repo":"zylon-ai/private-gpt","slug":"empty-dataframe-provided","errorCode":null,"errorMessage":"Empty dataframe provided.","messagePattern":"Empty dataframe provided\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"private_gpt/components/readers/nodes/table_node.py","lineNumber":342,"sourceCode":"                    for child in self.children\n                )\n\n        metadata_str = \"\"\n        description = \"\"\n        if metadata_mode != TreeMetadataMode.NONE:\n            metadata_str = self.get_metadata_str(mode=metadata_mode).strip()\n            description = (\n                f\"Table description: \\n{self.description}\\n\" if self.description else \"\"\n            )\n\n        content = f\"Content: \\n{content}\" if self.description else content\n        return metadata_str + description + content\n\n    def set_content(self, value: Any) -> None:\n        if not isinstance(value, TableNode.Meta):\n            raise ValueError(f\"Expected TableNode.Meta, got {type(value)}\")\n        if len(value.dataframe) == 0:\n            raise ValueError(\"Empty dataframe provided.\")\n\n        # Store content\n        self.df = value.dataframe\n        self.description = value.summary\n\n    def is_row_compatible(self, row: TableRowNode) -> bool:\n        return all(\n            col1 == col2\n            for col1, col2 in zip(self.df.columns, row.header, strict=False)\n        )\n\n    def add_row(self, row: list[Any]) -> None:\n        if len(row) != len(self.df.columns):\n            raise ValueError(\n                f\"Row length mismatch: {len(row)} != {len(self.df.columns)}\"\n            )\n        self.df.loc[len(self.df)] = row\n","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/zylon-ai/private-gpt/blob/4a030776a31a901ad80b1bf4d7faa2c1a367efbb/private_gpt/components/readers/nodes/table_node.py#L324-L360","documentation":"TableNode.set_content validates the incoming TableNode.Meta and refuses an empty dataframe (len(value.dataframe) == 0), because a table node with zero rows has no content to index or serialize. It raises ValueError before any state is mutated. Typically the emptiness originates upstream — a query/filter that returned no rows, or a reader that produced an empty table from an empty file.","triggerScenarios":"Calling TableNode.set_content(meta) where meta.dataframe is an empty DataFrame — e.g. ingesting a header-only CSV, applying a filter that drops all rows, or programmatically constructing a Meta from `pd.DataFrame()`.","commonSituations":"Ingesting empty CSV/TSV exports (common with scheduled jobs that had no data); delimiter misconfiguration producing zero parsed rows; ETL filters that occasionally empty the frame; test fixtures with empty dataframes.","solutions":["Skip table-node creation when the frame is empty: `if len(df) == 0: return` (or log and drop the document).","Fix the upstream reader/delimiter config if the source file genuinely has rows but none are parsed (wrong separator, wrong encoding).","If an empty table must be represented, emit metadata/description only rather than a TableNode.","Validate the source export job so header-only files are not generated."],"exampleFix":"# before\nnode.set_content(TableNode.Meta(dataframe=df, summary=\"...\"))  # ValueError: Empty dataframe\n\n# after\nif len(df) == 0:\n    logger.warning(\"Skipping empty table for %s\", source_name)\nelse:\n    node.set_content(TableNode.Meta(dataframe=df, summary=\"...\"))","handlingStrategy":"validation","validationCode":"def build_table_node(df, summary: str) -> TableNode | None:\n    if df is None or len(df) == 0:\n        logger.warning(\"Empty dataframe; skipping table node\")\n        return None\n    node = TableNode()\n    node.set_content(TableNode.Meta(dataframe=df, summary=summary))\n    return node","typeGuard":"def is_nonempty_dataframe(value: Any) -> bool:\n    import pandas as pd\n    return isinstance(value, pd.DataFrame) and len(value) > 0","tryCatchPattern":"try:\n    table_node.set_content(meta)\nexcept ValueError as e:\n    if \"Empty dataframe\" in str(e):\n        skip_document = True  # known-benign: header-only source\n    else:\n        raise","preventionTips":["Check len(df) before constructing table nodes.","Detect and route header-only exports away from table ingestion.","Unit-test parsers against empty and header-only fixtures."],"tags":["validation","table","dataframe","ingestion","empty-data"],"backgroundTag":null,"analyzedSha":"4a030776a31a901ad80b1bf4d7faa2c1a367efbb","analyzedAt":"2026-08-15T03:51:26.951Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}