PaddlePaddle/PaddleOCR · error · ValueError

Second argument needs to be a %s

Error message

Second argument needs to be a %s

What it means

Raised by TableToDocx (htmldocx-derived) in add_html_to_cell when the second argument is not a python-docx _Cell object. Before writing HTML content into a table cell, the parser verifies the target is a real docx cell so it can safely access cell.paragraphs and cell styles. Passing a merged-cell placeholder, a Table object, or None triggers it. The message interpolates the class object itself, so it prints like "<class 'docx.table._Cell'>".

Source

Thrown at ppstructure/recovery/table_process.py:219

    def get_tables(self):
        if not hasattr(self, "soup"):
            self.include_tables = False
            return
            # find other way to do it, or require this dependency?
        self.tables = self.ignore_nested_tables(self.soup.find_all("table"))
        self.table_no = 0

    def run_process(self, html):
        if self.bs and BeautifulSoup:
            self.soup = BeautifulSoup(html, "html.parser")
            html = str(self.soup)
        if self.include_tables:
            self.get_tables()
        self.feed(html)

    def add_html_to_cell(self, html, cell):
        if not isinstance(cell, docx.table._Cell):
            raise ValueError("Second argument needs to be a %s" % docx.table._Cell)
        unwanted_paragraph = cell.paragraphs[0]
        if unwanted_paragraph.text == "":
            delete_paragraph(unwanted_paragraph)
        self.set_initial_attrs(cell)
        self.run_process(html)
        # cells must end with a paragraph or will get message about corrupt file
        # https://stackoverflow.com/a/29287121
        if not self.doc.paragraphs:
            self.doc.add_paragraph("")

    def apply_paragraph_style(self, style=None):
        try:
            if style:
                self.paragraph.style = style
            elif self.paragraph_style:
                self.paragraph.style = self.paragraph_style
        except KeyError as e:
            raise ValueError(f"Unable to apply style {self.paragraph_style}.") from e

View on GitHub (pinned to 2661c7c0ef)

Solutions

  1. Pass an actual cell object: doc.add_table(...).rows[r].cells[c]
  2. If the target may be a merged span, resolve it via table.cell(r, c) which returns the spanning _Cell
  3. Add an isinstance check upstream and skip/handle non-cell targets instead of letting the parser raise

Example fix

# before
parser.add_html_to_cell(html, doc.tables[0].rows[0])  # a _Row, not a _Cell

# after
row = doc.tables[0].rows[0]
for cell in row.cells:
    parser.add_html_to_cell(html, cell)
Defensive patterns

Strategy: type-guard

Validate before calling

import docx.table
if not isinstance(cell, docx.table._Cell):
    raise TypeError(f'expected _Cell, got {type(cell).__name__}')
parser.add_html_to_cell(html, cell)

Type guard

import docx.table

def is_docx_cell(obj) -> bool:
    """True when obj is a python-docx table cell."""
    return isinstance(obj, docx.table._Cell)

Try / catch

try:
    parser.add_html_to_cell(html, cell)
except ValueError as e:
    if 'needs to be a' in str(e):
        raise TypeError(f'bad cell target: {type(cell).__name__}') from e
    raise

Prevention

When it happens

Trigger: Calling table_parser.add_html_to_cell(html, cell) where cell is not an instance of docx.table._Cell — e.g. a docx.table.Table, a string, or a cell obtained from an API that returned a different type.

Common situations: Custom table-recovery code that iterates a docx table and passes rows/tables instead of cells; handling merged cells where code indexes cell.tc_pr or substitutes None; version drift in python-docx where _Cell is imported from a different module path.

Related errors


AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14). Data as JSON: /api/errors/51eb01144f73e3b3. Report an issue: GitHub.