odysseus-dev/odysseus · error · HTTPException
Field schema sidecar missing for source PDF
Error message
Field schema sidecar missing for source PDF
What it means
Raised by POST /api/document/{doc_id}/export-pdf/preview with 404 when the source PDF file exists but load_field_sidecar(pdf_path) returns nothing — the JSON sidecar describing the form's field schema (names, labels, rects) was not generated or was lost. Without the sidecar the preview cannot map document values onto PDF fields, so the flow aborts even though the PDF itself is present.
Source
Thrown at routes/document/document_routes.py:1091
user = get_current_user(request)
db = SessionLocal()
try:
doc = db.query(Document).filter(Document.id == doc_id).first()
if not doc:
raise HTTPException(404, "Document not found")
_verify_doc_owner(db, doc, user)
upload_id = find_source_upload_id(doc.current_content or "")
if not upload_id:
raise HTTPException(400, "Document is not linked to a source PDF")
pdf_path = _locate_current_user_upload(request, upload_id, user)
if not pdf_path:
raise HTTPException(404, f"Source PDF {upload_id} not found in uploads")
fields = load_field_sidecar(pdf_path)
if not fields:
raise HTTPException(404, "Field schema sidecar missing for source PDF")
values = parse_markdown_to_values(doc.current_content or "")
field_meta = {f["name"]: f for f in fields}
preview = []
for name, current in values.items():
meta = field_meta.get(name)
if not meta:
continue
preview.append({
"name": name,
"label": meta.get("label") or name,
"type": meta.get("type"),
"options": meta.get("options") or [],
"page": meta.get("page"),
"value": current,
})
View on GitHub (pinned to f9235ebbf1)
Solutions
- Check for the sidecar file next to the PDF (same base name, .json) and inspect its contents.
- Regenerate the sidecar by re-running the form-field extraction step on the source PDF, or re-upload the PDF through the form-doc flow.
- If sidecars are routinely lost, make cleanup preserve both the PDF and its companion .json.
- Surface a distinct UI message telling the user to re-import the PDF so its schema is rebuilt.
Example fix
# before
fields = load_field_sidecar(pdf_path)
if not fields:
raise HTTPException(404, "Field schema sidecar missing for source PDF")
# after
fields = load_field_sidecar(pdf_path)
if not fields:
fields = extract_field_schema(pdf_path) # rebuild from the PDF itself
if fields:
save_field_sidecar(pdf_path, fields)
if not fields:
raise HTTPException(404, "Field schema sidecar missing for source PDF") Defensive patterns
Strategy: fallback
Validate before calling
import json, os
def sidecar_ok(pdf_path: str) -> bool:
side = os.path.splitext(pdf_path)[0] + ".json"
if not os.path.exists(side):
return False
try:
return len(json.load(open(side))) > 0
except (json.JSONDecodeError, OSError):
return False Try / catch
try:
p = requests.post(f"{base}/api/document/{doc}/export-pdf/preview")
except requests.HTTPError as e:
if e.response.status_code == 404 and "sidecar" in e.response.json().get("detail", ""):
offer_reimport(doc) # rebuild schema by re-importing the PDF
else:
raise Prevention
- Always generate the field sidecar during PDF-form ingestion.
- Make cleanup keep the .json companion next to each retained .pdf.
- Monitor sidecar presence when uploads are migrated between environments.
When it happens
Trigger: The PDF was uploaded through a path that skips sidecar generation (plain upload vs. form-doc ingestion); the sidecar file was deleted by cleanup while the PDF survived; a corrupted or empty sidecar file fails to parse into a truthy field list.
Common situations: Mixed ingestion pipelines where only one writes sidecars; storage cleanup keyed to file extension (e.g. keeping .pdf, removing .json); older uploads predating sidecar support.
Related errors
- Source PDF {upload_id} not found in uploads
- Source PDF {upload_id} not found
- Integration not found
- Calendar not found
- Event not found
AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14).
Data as JSON: /api/errors/643ad94366895687.
Report an issue: GitHub.