odysseus-dev/odysseus · info · HTTPException

No active stream for this session

Error message

No active stream for this session

What it means

GET /api/chat/stream_status/{session_id} returns 404 when the session has neither an entry in _active_streams nor an active detached run in agent_runs. The endpoint is a presence probe: 'detached': true is reported when only the background run exists.

Source

Thrown at routes/chat_routes.py:2432

        stopped = agent_runs.stop(session_id, _expected_run_id)
        return {"stopped": stopped}

    # ------------------------------------------------------------------ #
    # GET /api/chat/stream_status — check if a stream is active for a session
    # ------------------------------------------------------------------ #
    @router.get("/api/chat/stream_status/{session_id}")
    async def chat_stream_status(request: Request, session_id: str) -> Dict[str, Any]:
        _verify_session_owner(request, session_id)
        # A detached run can still be going even if _active_streams was popped;
        # report it as active so the client knows to reconnect via /resume.
        # Read once via .get() to avoid a KeyError race between the membership
        # check and the indexed read if a sibling stream's finally pops the
        # entry in between (same pattern _stream_set already uses).
        rec = _active_streams.get(session_id)
        if rec is None:
            if agent_runs.is_active(session_id):
                return {"status": "streaming", "detached": True}
            raise HTTPException(404, "No active stream for this session")
        return rec

    # ------------------------------------------------------------------ #
    # POST /api/inject_context
    # ------------------------------------------------------------------ #
    @router.post("/api/inject_context/{session_id}")
    async def inject_context(request: Request, session_id: str, context: str = Form(...)) -> Dict[str, str]:
        _verify_session_owner(request, session_id)
        try:
            sess = session_manager.get_session(session_id)
            msg = untrusted_context_message("injected research context", f"Research Context: {context}")
            sess.add_message(ChatMessage(msg["role"], msg["content"], metadata=msg.get("metadata")))
            session_manager.save_sessions()
            return {"status": "context_injected"}
        except KeyError:
            raise HTTPException(404, "Session not found")

    # ------------------------------------------------------------------ #

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Treat this 404 as 'idle' in the client (no stream, no run) rather than as an error
  2. Stop polling once 404 is returned repeatedly and the UI shows the chat as inactive
  3. If a run should be active, verify it was started detached and the server wasn't restarted

Example fix

// before
const rec = await fetch(statusUrl).then(r => r.json());
// after
const resp = await fetch(statusUrl);
if (resp.status === 404) { /* session idle: render idle UI */ }
const rec = await resp.json();
Defensive patterns

Strategy: try-catch

Try / catch

const resp = await fetch(statusUrl);
if (resp.status === 404) { renderIdleState(); return; }
const rec = await resp.json();

Prevention

When it happens

Trigger: Polling stream status for a session with no open SSE stream and no detached run — idle chats, finished runs whose stream record was popped by the finally block, or never-started sessions.

Common situations: Client status polling loop continuing after a stream ends; reconnect logic probing a chat that was closed; race where the stream record was just popped but no detached run replaced it.

Related errors


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