odysseus-dev/odysseus · error · HTTPException

Failed to create document for PDF

Error message

Failed to create document for PDF

What it means

500 raised by POST /api/documents/import-pdf when the document-creation helper (create_form_pdf_document / create_plain_pdf_document for PDFs with form fields, or create_plain_pdf_document otherwise) returned a falsy doc_id. The PDF itself was saved successfully; only the DB insert of the Document row failed or was skipped.

Source

Thrown at routes/document/document_routes.py:304

            fields = extract_fields(pdf_path)
            save_field_sidecar(pdf_path, fields)
            doc_id = create_form_markdown_document(
                session_id=session_id,
                fields=fields,
                upload_id=upload_id,
                title=title,
                intro_text=body_text,
            )
        else:
            doc_id = create_plain_pdf_document(
                session_id=session_id,
                upload_id=upload_id,
                title=title,
                body_text=body_text,
            )

        if not doc_id:
            raise HTTPException(500, "Failed to create document for PDF")

        db = SessionLocal()
        try:
            doc = db.query(Document).filter(Document.id == doc_id).first()
            if not doc:
                raise HTTPException(500, "Created document not found")
            # The PDF doc creators stamp owner from the session only; a
            # session-less library import leaves owner NULL, which the Library's
            # owner filter then hides. Stamp the requesting user so it shows.
            if not doc.owner and user:
                doc.owner = user
                db.commit()
                db.refresh(doc)
            return _doc_to_dict(doc)
        finally:
            db.close()

    # ---- GET /api/documents/library ----

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Check server logs for any error/warning from the create_*_pdf_document helper just before the 500.
  2. Reproduce with session_id supplied vs omitted to see which code path (form vs plain) returns None.
  3. Read create_form_pdf_document / create_plain_pdf_document and find every `return None` branch — fix or log the branch taken.
  4. If the None return hides an exception, let it propagate (or raise HTTPException) instead of returning None.

Example fix

# before
doc_id = create_plain_pdf_document(...)  # returns None on internal error, endpoint 500s opaquely
# after
# in the helper: raise/log the cause, or in the route:
if not doc_id:
    logger.error(f"pdf doc creator returned None for upload {upload_id} (form={is_form})")
    raise HTTPException(500, "Failed to create document for PDF")
Defensive patterns

Strategy: try-catch

Try / catch

try { const r = await api.post('/api/documents/import-pdf', fd); }
catch (e) {
  if (/Failed to create document for PDF/.test(e.message)) {
    // PDF stored but DB row not created — do not re-upload the same file blindly
    notify('Import failed at document creation; contact support with the upload id');
  } else throw e;
}

Prevention

When it happens

Trigger: The PDF is a form (has_form_fields true) and create_form_pdf_document hits an internal error and returns None; create_plain_pdf_document returns None because session_id points to a session its own check rejects; DB constraint failure inside the creator that is swallowed and converted to a None return.

Common situations: Importing a session-less PDF while the creator helper secretly requires a session; AcroForm PDFs exercising the form-document code path for the first time; creator helpers that catch exceptions broadly and return None, hiding the real error.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/cb0a322f8e11983c. Report an issue: GitHub.