odysseus-dev/odysseus · error · HTTPException

Integration not found

Error message

Integration not found

What it means

HTTP 404 raised by PUT /integrations/{integration_id} when update_integration(integration_id, body) returns falsy — the store has no integration with that id. Ids are assigned at creation (add_integration) and persisted via load/save of the integrations store.

Source

Thrown at routes/auth_routes.py:770

    async def create_integration(request: Request):
        """Create a new integration (admin only)."""
        user = _get_current_user(request)
        if not user or not auth_manager.is_admin(user):
            raise HTTPException(403, "Admin only")
        body = await request.json()
        item = add_integration(body)
        return {"ok": True, "integration": mask_integration_secret(item)}

    @router.put("/integrations/{integration_id}")
    async def update_integration_route(integration_id: str, request: Request):
        """Update an existing integration (admin only)."""
        user = _get_current_user(request)
        if not user or not auth_manager.is_admin(user):
            raise HTTPException(403, "Admin only")
        body = await request.json()
        item = update_integration(integration_id, body)
        if not item:
            raise HTTPException(404, "Integration not found")
        return {"ok": True, "integration": mask_integration_secret(item)}

    @router.delete("/integrations/{integration_id}")
    async def delete_integration_route(integration_id: str, request: Request):
        """Delete an integration (admin only)."""
        user = _get_current_user(request)
        if not user or not auth_manager.is_admin(user):
            raise HTTPException(403, "Admin only")
        ok = delete_integration(integration_id)
        if not ok:
            raise HTTPException(404, "Integration not found")
        return {"ok": True}

    @router.post("/integrations/{integration_id}/test")
    async def test_integration_route(integration_id: str, request: Request):
        """Test connectivity to an integration (admin only)."""
        user = _get_current_user(request)
        if not user or not auth_manager.is_admin(user):

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Re-fetch GET /integrations and use a current id.
  2. If the integration was deleted, re-create it via POST instead of PUT.
  3. Treat 404 on update as a signal to refresh the admin panel state.
Defensive patterns

Strategy: validation

Validate before calling

async function integrationExists(id) {
  const {integrations} = await (await fetch('/integrations')).json();
  return integrations.some(i => i.id === id);
}

Try / catch

try { await updateIntegration(id, body); }
catch (e) {
  if (e.status === 404) { await refreshList(); /* offer re-create */ }
  else throw e;
}

Prevention

When it happens

Trigger: PUT /integrations/{id} after the integration was deleted in another tab/session; stale id in the UI after a settings file reset; typo or truncated id in the path parameter.

Common situations: Two admins editing concurrently — one deletes while the other saves; the integrations store file recreated from scratch (migration or manual edit); client cached an old id list.

Related errors


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