zylon-ai/private-gpt · error · ValueError
No content could be extracted from document source (type={do
Error message
No content could be extracted from document source (type={doc_block.source.type!r}). What it means
ValueError from _process_document (chat history preprocessor). It converts a DocumentBlock's source to text via source.to_text(convert_service) on a worker thread; if the result is empty or None, no LITextBlock can be built and it raises, naming the source type. This guards the ingestion path where every document attachment must yield text for the chat history.
Source
Thrown at private_gpt/components/chat/processors/chat_history/documents/document_preprocessor.py:62
doc_index: int
reference: str | None = None
content: str | list[ResultContentBlockType] | None = None
error_detail: str | None = None
class DocumentProcessingResponse(BaseModel):
message: ChatMessage | None = None
processing_status: DocumentProcessingStatus | None = None
chat_history: list[ChatMessage] | None = None
async def _process_document(
doc_block: DocumentBlock,
convert_service: DocumentConverter,
) -> LITextBlock:
text = await asyncio.to_thread(doc_block.source.to_text, convert_service)
if not text:
raise ValueError(
f"No content could be extracted from document source "
f"(type={doc_block.source.type!r})."
)
parts: list[str] = []
if doc_block.title:
parts.append(f"Title: {doc_block.title}")
if doc_block.context:
parts.append(f"Context: {doc_block.context}")
parts.append(text)
return LITextBlock(text="\n\n".join(parts))
async def preprocess_document_message(
message: ChatMessage,
convert_service: DocumentConverter,
max_concurrency: int | None = None,View on GitHub (pinned to 4a030776a3)
Solutions
- Open the uploaded file locally and confirm it actually contains extractable text (pdftotext, cat).
- For scanned PDFs/images, enable an OCR-capable converter or OCR the file before upload.
- Reject empty/unsupported files at the API boundary before they reach the chat pipeline (check size and content type).
- Check the reported source type in the message to see which converter branch returned nothing.
Example fix
// before # upload scanned.pdf (no text layer) -> chat request ValueError: No content could be extracted from document source (type='file'). // after # OCR first, then upload $ ocrmypdf in.pdf out.pdf && curl -F file=@out.pdf ...
Defensive patterns
Strategy: validation
Validate before calling
text = await asyncio.to_thread(doc_block.source.to_text, convert_service)
if not text or not text.strip():
raise HTTPException(422, f"Document yielded no text (source type={doc_block.source.type!r})") Type guard
def document_has_extractable_text(path: str) -> bool:
import subprocess
return subprocess.run(["pdftotext", path, "-"], capture_output=True).stdout.strip() != b"" Try / catch
try:
block = await _process_document(doc_block, converter)
except ValueError as e:
raise HTTPException(422, str(e)) from e Prevention
- Reject zero-byte and unsupported uploads at the API boundary.
- OCR scanned PDFs/images before ingestion.
- Verify extractability client-side for PDFs (pdftotext).
- Surface the source type in error reports to speed diagnosis.
When it happens
Trigger: Uploading an image/PDF/binary whose conversion yields nothing (empty PDF, scanned image without OCR, corrupt file), a 0-byte file, or a source type whose to_text returns '' for this converter configuration.
Common situations: Scanned PDFs with no OCR backend configured; empty or password-protected documents; unsupported formats that the DocumentConverter silently skips; upload endpoints accepting files without content checks.
Related errors
- No valid content found in the conversion result
- Invalid system item in list (dict): {item}
- Invalid system item in list: {item}
- Invalid system specification: {system}
- No user messages found in the chat history.
AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15).
Data as JSON: /api/errors/8666ee0f67b6563d.
Report an issue: GitHub.