odysseus-dev/odysseus · critical · HTTPException

Upload handler not configured

Error message

Upload handler not configured

What it means

Raised by POST /api/documents/import-pdf when the route factory was built without an upload handler (setup_document_routes(session_manager, upload_handler=None)). The handler is the component that persists uploaded files and returns metadata; without it the endpoint cannot save any PDF and fails fast with a 500 before touching the file.

Source

Thrown at routes/document/document_routes.py:257

        )
        from src.document_processor import _process_pdf, strip_pdf_content_marker
        import os

        from src.auth_helpers import require_privilege
        user = require_privilege(request, "can_use_documents")

        # session_id is optional — a library import isn't tied to a chat. When
        # given, validate it; otherwise the PDF becomes a session-less library
        # doc (the doc creators below already handle a missing session).
        if session_id:
            db = SessionLocal()
            try:
                _get_session_or_404(db, session_id, user)
            finally:
                db.close()

        if upload_handler is None:
            raise HTTPException(500, "Upload handler not configured")

        client_ip = request.client.host if request.client else "unknown"
        try:
            meta = upload_handler.save_upload(file, client_ip, owner=user)
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"PDF import save_upload failed: {e}")
            raise HTTPException(500, f"Upload failed: {e}")

        upload_id = meta["id"]
        pdf_path = _locate_current_user_upload(request, upload_id, user)
        if not pdf_path:
            raise HTTPException(500, "Saved PDF could not be located")

        title = os.path.splitext(meta.get("original_name") or meta.get("name") or upload_id)[0]
        try:
            body_text = strip_pdf_content_marker(_process_pdf(pdf_path, owner=user))

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Find where setup_document_routes is called and pass the app's UploadHandler instance as the second argument.
  2. Import src.upload_handler.UploadHandler, construct it with the configured base/upload dir, and inject it during router setup.
  3. Add a startup assertion or test that upload_handler is not None before serving, so misconfiguration fails at boot rather than at first PDF import.

Example fix

# before
router = setup_document_routes(session_manager)  # upload_handler defaults to None -> 500
# after
from src.upload_handler import UploadHandler
router = setup_document_routes(session_manager, UploadHandler(base_dir, upload_dir))
Defensive patterns

Strategy: validation

Validate before calling

// before mounting, assert the wiring
import { setup_document_routes } from './routes/document/document_routes';
if (!uploadHandler) throw new Error('setup_document_routes requires an UploadHandler');
app.use(setup_document_routes(sessionManager, uploadHandler));

Type guard

def has_upload_handler(router_factory_kwargs: dict) -> bool:
    return router_factory_kwargs.get('upload_handler') is not None

Try / catch

try { await api.post('/api/documents/import-pdf', fd); }
catch (e) { if (e.message.includes('Upload handler not configured')) { /* config bug, file an alert, do not retry */ } throw e; }

Prevention

When it happens

Trigger: Calling setup_document_routes() without the upload_handler argument (it defaults to None), or a wiring/regression where the dependency-injection step that constructs UploadHandler was skipped during app startup.

Common situations: New deployment or test harness that mounts document routes directly instead of through the main app factory; refactor renamed the UploadHandler parameter and callers now pass None; running route unit tests without the upload fixture.

Related errors


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