Skip to content

ValueError: max() iterable argument is empty in _extract_headers when table segment has no dict rows #6

Description

@xfab-roy

Bug Description

_extract_headers in merge_table.py crashes with ValueError: max() iterable argument is empty when a table segment contains only separator rows (or rows where row['tr'] is a string rather than a dict).

Root Cause

In merge_table.py line 25-28:

max_cols = max(
    len(row['tr']) for row in segment
    if _is_table_row(row) and isinstance(row['tr'], dict)
)

The generator filters for rows where row['tr'] is a dict, but when all rows in a segment have row['tr'] as a string (e.g. 'table_separator'), the generator yields nothing and max() raises ValueError.

Minimal Reproducible Example

from markdown_to_data import Markdown

# A lone separator line gets classified as a table row but has no dict data
md = Markdown("---|---")
print(md.md_dict)  # ValueError: max() iterable argument is empty

All of these crash:

Markdown("---|---")
Markdown("|---|---|")
Markdown("text\n---|---\nmore text")
Markdown("# Heading\n\n---|---\n\nParagraph")

In real-world documents this commonly happens with content like horizontal rules written as ---|---, or technical text near pipe characters that creates isolated separator-only segments.

Full Traceback

Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "markdown_to_data/markdown_to_data.py", line 107, in md_dict
    self._md_dict = hierarchy_with_merged_markdown_lines(self.md_list)
  File "markdown_to_data/markdown_to_data.py", line 101, in md_list
    self._md_list = merge_classified_markdown_lines(classified_list=self.classified_lines)
  File "markdown_to_data/to_python/to_python_objects.py", line 55, in merge_classified_markdown_lines
    merged_elements = merge_tables(classified_md=merged_elements)
  File "markdown_to_data/to_python/merging_multiline_objects/merge_table.py", line 112, in merge_tables
    result.append(_process_table_segment(current_segment))
  File "markdown_to_data/to_python/merging_multiline_objects/merge_table.py", line 79, in _process_table_segment
    headers = _extract_headers(segment)
  File "markdown_to_data/to_python/merging_multiline_objects/merge_table.py", line 25, in _extract_headers
    max_cols = max(
ValueError: max() iterable argument is empty

Impact

This is particularly problematic for technical documents containing patterns that get classified as table separators in non-table contexts. The error crashes the entire parsing pipeline — not just the bad table segment — so all hierarchical structure (headers, lists, code blocks) from the document is lost.

In my use case, ~15% of a 1,280-document corpus (189 files) hit this error, despite having rich heading structure that would otherwise parse fine.

Suggested Fix

Add a default parameter to the max() call and handle the empty case:

max_cols = max(
    (len(row['tr']) for row in segment
     if _is_table_row(row) and isinstance(row['tr'], dict)),
    default=0,
)

if max_cols == 0:
    # No valid table rows found — skip or convert to paragraphs
    return {'paragraph': '---'}  # or however you'd like to handle it

Environment

  • markdown-to-data version: 2.0.1 (also verified unfixed in 2.0.2)
  • Python 3.12

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions