{"record":{"id":"cb0a322f8e11983c","repo":"odysseus-dev/odysseus","slug":"failed-to-create-document-for-pdf","errorCode":null,"errorMessage":"Failed to create document for PDF","messagePattern":"Failed to create document for PDF","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"routes/document/document_routes.py","lineNumber":304,"sourceCode":"            fields = extract_fields(pdf_path)\n            save_field_sidecar(pdf_path, fields)\n            doc_id = create_form_markdown_document(\n                session_id=session_id,\n                fields=fields,\n                upload_id=upload_id,\n                title=title,\n                intro_text=body_text,\n            )\n        else:\n            doc_id = create_plain_pdf_document(\n                session_id=session_id,\n                upload_id=upload_id,\n                title=title,\n                body_text=body_text,\n            )\n\n        if not doc_id:\n            raise HTTPException(500, \"Failed to create document for PDF\")\n\n        db = SessionLocal()\n        try:\n            doc = db.query(Document).filter(Document.id == doc_id).first()\n            if not doc:\n                raise HTTPException(500, \"Created document not found\")\n            # The PDF doc creators stamp owner from the session only; a\n            # session-less library import leaves owner NULL, which the Library's\n            # owner filter then hides. Stamp the requesting user so it shows.\n            if not doc.owner and user:\n                doc.owner = user\n                db.commit()\n                db.refresh(doc)\n            return _doc_to_dict(doc)\n        finally:\n            db.close()\n\n    # ---- GET /api/documents/library ----","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/odysseus-dev/odysseus/blob/f9235ebbf13f693a6fd29ce70b097f6ec83705bf/routes/document/document_routes.py#L286-L322","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check server logs for any error/warning from the create_*_pdf_document helper just before the 500.","Reproduce with session_id supplied vs omitted to see which code path (form vs plain) returns None.","Read create_form_pdf_document / create_plain_pdf_document and find every `return None` branch — fix or log the branch taken.","If the None return hides an exception, let it propagate (or raise HTTPException) instead of returning None."],"exampleFix":"# before\ndoc_id = create_plain_pdf_document(...)  # returns None on internal error, endpoint 500s opaquely\n# after\n# in the helper: raise/log the cause, or in the route:\nif not doc_id:\n    logger.error(f\"pdf doc creator returned None for upload {upload_id} (form={is_form})\")\n    raise HTTPException(500, \"Failed to create document for PDF\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { const r = await api.post('/api/documents/import-pdf', fd); }\ncatch (e) {\n  if (/Failed to create document for PDF/.test(e.message)) {\n    // PDF stored but DB row not created — do not re-upload the same file blindly\n    notify('Import failed at document creation; contact support with the upload id');\n  } else throw e;\n}","preventionTips":["Ensure session_id passed to import matches an existing session","Server-side: make create_* helpers raise instead of returning None","Watch logs for the form-PDF code path when supporting AcroForm imports"],"tags":["pdf","database","http-500","error-swallowing"],"backgroundTag":null,"analyzedSha":"f9235ebbf13f693a6fd29ce70b097f6ec83705bf","analyzedAt":"2026-08-14T21:47:48.359Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}