docling-project/docling · error · TypeError
Unsupported input type: {type(self.path_or_stream)}
Error message
Unsupported input type: {type(self.path_or_stream)} What it means
EmailDocumentBackend._read_bytes() only accepts BytesIO or Path inputs and raises TypeError for anything else (str paths, file objects opened in text mode, TemporaryFile wrappers, etc.). Because the call sits inside the init try-block, callers normally see it wrapped in the email backend's DocumentLoadError, with the TypeError as __cause__.
Source
Thrown at docling/backend/email_backend.py:111
self.is_msg = raw.startswith(_MSG_MAGIC)
if self.is_msg:
raw = self._msg_to_rfc822_bytes(raw)
self.mail = mailparser.parse_from_bytes(raw)
self.valid = self.mail is not None
except ImportError:
raise
except Exception as exc:
raise DocumentLoadError(
f"Could not initialize email backend for file with hash {self.document_hash}."
) from exc
def _read_bytes(self) -> bytes:
if isinstance(self.path_or_stream, BytesIO):
return self.path_or_stream.getvalue()
if isinstance(self.path_or_stream, Path):
return self.path_or_stream.read_bytes()
raise TypeError(f"Unsupported input type: {type(self.path_or_stream)}")
@staticmethod
def _header_safe(value: str) -> str:
# Email header values must be single-line; collapse CR/LF to spaces so a
# crafted .msg cannot inject headers and EmailMessage does not reject it.
return value.replace("\r", " ").replace("\n", " ").strip()
@staticmethod
def _msg_to_rfc822_bytes(data: bytes) -> bytes:
"""Project an Outlook ``.msg`` (OLE2/CFB) onto RFC 822 bytes.
python-oxmsg reads the MAPI message; we assemble a standard
``email.message.EmailMessage`` from it so the ``.msg`` path shares the
exact body, HTML, address, and attachment handling used for ``.eml``
input.
"""
if not _OXMSG_AVAILABLE:
raise ImportError(_MSG_INSTALL_HINT) from _OXMSG_IMPORT_ERRORView on GitHub (pinned to 61d76f1ff3)
Solutions
- Convert str paths to pathlib.Path before calling the API
- Wrap other binary file objects: BytesIO(open(p,'rb').read())
- Never pass StringIO or text-mode handles; the backend needs bytes
Example fix
# before
backend = EmailDocumentBackend(in_doc, '/data/mail.eml') # str not accepted
# after
from pathlib import Path
backend = EmailDocumentBackend(in_doc, Path('/data/mail.eml'))
# or for streams: EmailDocumentBackend(in_doc, BytesIO(raw_bytes)) Defensive patterns
Strategy: type-guard
Validate before calling
from io import BytesIO
from pathlib import Path
def normalize(src):
if isinstance(src, str):
return Path(src)
if isinstance(src, Path):
return src
if isinstance(src, BytesIO):
return src
if hasattr(src, 'read'):
return BytesIO(src.read())
raise TypeError(f'unsupported source: {type(src)!r}') Type guard
def is_accepted_source(src) -> bool:
return isinstance(src, (BytesIO, Path)) Prevention
- Normalize all inputs to Path or BytesIO at your service boundary
- Never forward raw open() handles or StringIO to Docling backends
When it happens
Trigger: Passing a string path instead of pathlib.Path, an open() file object, an io.FileIO, or any stream type other than BytesIO (e.g. io.StringIO) as path_or_stream to the email backend.
Common situations: Wrapping Docling in a service that forwards urllib/tempfile handles; legacy code using os.path strings; tests using StringIO for text fixtures.
Related errors
- Unexpected: {type(self.path_or_stream)=}
- The 'mail-parser' package is required to process email files
- Could not initialize email backend for file with hash {self.
- The 'python-oxmsg' package is required to process Outlook .m
- Cannot convert doc with {self.document_hash} because the bac
AI-assisted analysis of docling-project/docling@61d76f1ff3 (2026-08-14).
Data as JSON: /api/errors/949b074eac68e044.
Report an issue: GitHub.