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
- Re-fetch GET /integrations and use a current id.
- If the integration was deleted, re-create it via POST instead of PUT.
- 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
- Keep the integrations list as the single source of ids in UI state.
- After any delete elsewhere, invalidate cached ids.
- On 404, re-fetch and diff instead of blindly retrying.
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.