docling-project/docling · error · RuntimeError
Expected an OpenDocument {self._odf_type!r} but got {self.od
Error message
Expected an OpenDocument {self._odf_type!r} but got {self.odf_obj.get_type()!r} What it means
RuntimeError raised in _OdfBaseBackend.__init__ after successfully loading an ODF package whose odfdo get_type() does not match the subclass's _odf_type ('text' for ODT, 'presentation' for ODP, 'spreadsheet' for ODS). It prevents, e.g., the ODT backend from walking a spreadsheet body.
Source
Thrown at docling/backend/opendocument_backend.py:169
_odf_type: str = "" # "text", "spreadsheet" or "presentation"
@override
def __init__(
self,
in_doc: InputDocument,
path_or_stream: BytesIO | Path,
options: OdsBackendOptions | None = None,
) -> None:
if not _ODFDO_AVAILABLE:
raise ImportError(_INSTALL_HINT) from _ODFDO_IMPORT_ERROR
super().__init__(in_doc, path_or_stream, options)
self.path_or_stream: BytesIO | Path = path_or_stream
self.valid: bool = False
self.odf_obj: OdfDocument = _load_odf_document(
path_or_stream, self.document_hash
)
if self._odf_type and self.odf_obj.get_type() != self._odf_type:
raise RuntimeError(
f"Expected an OpenDocument {self._odf_type!r} but got "
f"{self.odf_obj.get_type()!r}"
)
self.valid = True
@override
def is_valid(self) -> bool:
return self.valid
@override
def unload(self):
if isinstance(self.path_or_stream, BytesIO):
self.path_or_stream.close()
self.path_or_stream = None
def _find_true_data_bounds(table: OdfTable) -> tuple[int, int, int, int]:
"""Find the true data boundaries (min/max rows and columns) in an ODS table.View on GitHub (pinned to 61d76f1ff3)
Solutions
- Detect the true type with odfdo or by reading the ODF mimetype entry and dispatch to the matching backend.
- Fix the file extension to match the actual document type and retry.
- Re-save the document from its native application with the correct type.
- In custom pipelines, key InputFormat off python-magic/filetype detection rather than the filename suffix.
Example fix
# before
conv = DocumentConverter(format=[InputFormat.ODT])
res = conv.convert('actually_a_sheet.odt') # RuntimeError: expected 'text' got 'spreadsheet'
# after
import filetype # or read the ODF 'mimetype' entry
kind = filetype.guess_mime(path)
fmt = {'application/vnd.oasis.opendocument.spreadsheet': InputFormat.ODS,
'application/vnd.oasis.opendocument.text': InputFormat.ODT,
'application/vnd.oasis.opendocument.presentation': InputFormat.ODP}[kind]
res = DocumentConverter(format=[fmt]).convert(path) Defensive patterns
Strategy: validation
Validate before calling
import zipfile
with zipfile.ZipFile(path) as z:
odf_type = z.read('mimetype').decode()
# map mimetype -> InputFormat and dispatch accordingly Try / catch
try:
backend = OdsBackendClass(in_doc, path)
except RuntimeError as e:
if 'Expected an OpenDocument' in str(e):
retry_with_correct_backend(detect_odf_type(path)) Prevention
- Read the ODF 'mimetype' entry and route by it, not by file extension
- Use content-based detection for user uploads
- Keep a mimetype->InputFormat map next to your dispatcher
When it happens
Trigger: A .ods file renamed to .odt (or any ODF type/format mismatch) is dispatched to the wrong backend by extension-based format detection; the mimetype inside content.xml disagrees with the backend's expectation.
Common situations: User-uploaded files with wrong extensions, pipelines that guess InputFormat from the suffix instead of MIME sniffing, mixed ODF exports misnamed during bulk conversion.
Related errors
- Incompatible file format {self.input_format} was passed to I
- OpenDocument backend could not load document with hash {docu
- The 'odfdo' package is required to process OpenDocument file
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/0e0d0ac3f831be03.
Report an issue: GitHub.