odysseus-dev/odysseus · error · HTTPException

Email integration is not available

Error message

Email integration is not available

What it means

Raised as HTTP 503 by GET /api/codex/emails when email_list_endpoint is None — setup_codex_routes failed to find the endpoint for GET /api/email/list on the email router passed to it. The codex surface is a proxy over the core email integration; if the underlying router was not wired (or its route path/method changed), the proxy reports service-unavailable rather than crashing.

Source

Thrown at routes/codex_routes.py:264

        owner = _scope_owner(request, allowed)
        args = dict(body)
        args["action"] = action
        return await do_manage_notes(json.dumps(args), owner=owner)

    @router.get("/emails")
    async def list_emails(
        request: Request,
        folder: str = "INBOX",
        limit: int = 10,
        offset: int = 0,
        filter: str = "all",
        from_addr: str | None = None,
        account_id: str | None = None,
        has_attachments: int = 0,
    ):
        owner = _scope_owner(request, EMAIL_READ_SCOPES)
        if email_list_endpoint is None:
            raise HTTPException(503, "Email integration is not available")
        limit = max(1, min(int(limit or 10), 50))
        offset = max(0, int(offset or 0))
        if account_id:
            from routes.email_helpers import _assert_owns_account

            _assert_owns_account(account_id, owner)
        return await email_list_endpoint(
            folder=folder,
            limit=limit,
            offset=offset,
            filter=filter,
            from_addr=from_addr,
            account_id=account_id,
            has_attachments=has_attachments,
            cache_bust=None,
            owner=owner,
        )

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Confirm the email integration is enabled and its router is registered — hit GET /api/email/list directly; if that 404s too, the integration is not mounted.
  2. Check the call site of setup_codex_routes to ensure email_router is passed and non-None.
  3. Align versions: upgrade so codex_routes' _find_endpoint path matches the current email router layout.
  4. Re-enable the email feature flag / dependency (e.g. installed mail provider) and restart.

Example fix

# before
app.include_router(setup_codex_routes(email_router=None, ...))

# after
from routes.email_routes import build_email_router
app.include_router(setup_codex_routes(email_router=build_email_router(), ...))
Defensive patterns

Strategy: validation

Validate before calling

async function codexEmailsReady() {
  const core = await fetch('/api/email/list?limit=1');
  return core.ok; // if core email API is dead, codex proxy will 503
}

Try / catch

try { r = await codexListEmails() } catch (e) { if (e.status === 503) { disableEmailFeatures(); notify('Email integration not available') } else throw }

Prevention

When it happens

Trigger: Calling /api/codex/emails when setup_codex_routes was invoked with email_router=None, an empty router, or one whose /api/email/list route was renamed/removed in a newer version.

Common situations: Email integration disabled at startup by config; version skew where codex_routes looks up an old email route path; a custom app.py that forgets to pass the email router into setup_codex_routes.

Related errors


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