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 eView on GitHub (pinned to 2661c7c0ef)
Solutions
- Pass an actual cell object: doc.add_table(...).rows[r].cells[c]
- If the target may be a merged span, resolve it via table.cell(r, c) which returns the spanning _Cell
- 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
- Always obtain cells via table.cell(r, c) or row.cells[c], never pass rows/tables
- Type-annotate cell parameters as docx.table._Cell so mypy catches misuse
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
- Unable to apply style {self.paragraph_style}.
- Environment Variable CUDA_VISIBLE_DEVICES is not set correct
- The input data is inconsistent with expectations.
- Environment Variable CUDA_VISIBLE_DEVICES is not set correct
- The input data is inconsistent with expectations.
AI-assisted analysis of PaddlePaddle/PaddleOCR@2661c7c0ef (2026-08-14).
Data as JSON: /api/errors/51eb01144f73e3b3.
Report an issue: GitHub.