odysseus-dev/odysseus · error · HTTPException

Selected model endpoint was removed. Pick another model in S

Error message

Selected model endpoint was removed. Pick another model in Settings.

What it means

The session references an endpoint (model provider route) that no longer exists; _clear_orphaned_session_endpoint detected the endpoint was deleted, cleared it from the session, and the handler rejects with 400 telling the user to re-pick a model. This prevents calls to a dead upstream URL.

Source

Thrown at routes/chat_routes.py:700

        message = chat_request.message
        session = chat_request.session
        att_ids = chat_request.attachments or []
        use_web = chat_request.use_web
        use_research = chat_request.use_research
        time_filter = chat_request.time_filter
        preset_id = chat_request.preset_id

        # Verify the caller owns this session before loading it.
        # Without this, any authenticated user can post into another user's chat.
        _verify_session_owner(request, session)

        try:
            sess = session_manager.get_session(session)
        except KeyError:
            raise HTTPException(404, f"Session '{session}' not found")
        owner = effective_user(request)
        if _clear_orphaned_session_endpoint(sess, owner=owner):
            raise HTTPException(400, "Selected model endpoint was removed. Pick another model in Settings.")

        # Empty model + live endpoint = setup race (Issue #587). Repair from
        # the endpoint's cached model list before privilege checks, which
        # otherwise see "" and behave inconsistently with the allowlist.
        _recover_empty_session_model(sess, session, owner=owner)
        if not getattr(sess, "model", "").strip():
            raise HTTPException(
                400,
                "No model selected for this chat. Open the model picker and choose one before sending.",
            )
        if not (getattr(sess, "endpoint_url", "") or "").strip():
            raise HTTPException(400, "Selected model endpoint is not configured")

        # Same allowed_models + daily-cap gate as chat_stream (mirror so the
        # non-streaming path can't be used to bypass).
        _enforce_chat_privileges(request, sess)

        tool_policy = build_effective_tool_policy(last_user_message=message)

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Open Settings in the client, pick a live endpoint/model for this chat, then resend
  2. If the endpoint should exist, re-create it in endpoint management and re-select it
  3. Administrators: warn users before deleting endpoints that sessions depend on
Defensive patterns

Strategy: validation

Validate before calling

const endpoints = await fetch('/api/endpoints').then(r=>r.json());
if (!endpoints.some(ep => ep.id === session.endpoint_id)) { promptEndpointRebind(); }

Try / catch

try { await send(...); } catch (e) { if (e.status === 400 && /endpoint was removed/.test(e.message)) openSettingsForModelPick(); else throw e; }

Prevention

When it happens

Trigger: Endpoint deleted or re-created in Settings after the session was bound to it; session restored from backup referencing an endpoint ID that was removed; multi-admin environments where one admin prunes endpoints.

Common situations: User had a chat open on a custom OpenAI-compatible endpoint that was later deleted; migration or cleanup scripts removed endpoint records while sessions still pointed at them.

Related errors


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