zylon-ai/private-gpt · error · ValueError
Header and content length mismatch: {len(value.header)} != {
Error message
Header and content length mismatch: {len(value.header)} != {len(value.content)} What it means
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.
Source
Thrown at private_gpt/components/readers/nodes/table_node.py:182
) -> dict[str, Any]:
encoder = NpEncoder()
d = super().model_dump(
include_parent=include_parent, include_children=include_children, **kwargs
)
d["content"] = encoder.encode(d["content"])
return d
@classmethod
def from_dict(cls, data: builtins.dict[str, Any], **kwargs: Any) -> Self:
encoder = NpEncoder()
data["content"] = encoder.decode(data["content"])
return super().from_dict(data, **kwargs)
def set_content(self, value: Any) -> None:
if not isinstance(value, TableRowNode.Meta):
raise ValueError(f"Expected TableRowNode.Meta, got {type(value)}")
if len(value.header) != len(value.content):
raise ValueError(
f"Header and content length mismatch: {len(value.header)} != {len(value.content)}"
)
# Store content
self.header = value.header
self.content = value.content
def is_first_row(self) -> bool:
if not self.parent:
return False
siblings = self.parent.children
if not siblings:
return False
# Validate idx - defensive check for partial loading
current_index = self.idx if 0 <= self.idx < len(siblings) else None
if current_index is not None and siblings[current_index] is not self:View on GitHub (pinned to 4a030776a3)
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.
Example fix
# before meta = TableRowNode.Meta(header=["a", "b", "c"], content=["1", "2"]) node.set_content(meta) # ValueError: mismatch 3 != 2 # after row = ["1", "2"] row = row[:3] + [""] * (3 - len(row)) meta = TableRowNode.Meta(header=["a", "b", "c"], content=row) node.set_content(meta)
Defensive patterns
Strategy: validation
Validate before calling
def make_row_meta(header: list[str], content: list[Any]) -> TableRowNode.Meta | None:
if len(header) != len(content):
logger.warning("Dropping ragged row: %d header vs %d values", len(header), len(content))
return None
return TableRowNode.Meta(header=header, content=content) Type guard
def is_valid_table_row(value: Any) -> bool:
return (
isinstance(value, TableRowNode.Meta)
and isinstance(value.header, list)
and isinstance(value.content, list)
and len(value.header) == len(value.content)
) Try / catch
try:
node.set_content(meta)
except ValueError as e:
logger.warning("Rejected malformed row: %s", e)
# skip this row, keep ingesting the rest Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Empty dataframe provided.
- Invalid system item in list (dict): {item}
- zpgt.ingest.invalid_file_size.error
- Chunk size must be greater than 0.
- No reader registered for extension: {extension}
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/4e4c20ef0e02e283.
Report an issue: GitHub.