odysseus-dev/odysseus · error · HTTPException

Topic analysis failed: {e}

Error message

Topic analysis failed: {e}

What it means

GET /api/conversations/topics wraps analyze_topics(session_manager, owner) in a blanket except that returns 500 'Topic analysis failed: {e}'. Any failure inside topic analysis — empty/malformed histories, text-processing exceptions, DB reads during iteration — surfaces here with the raw exception interpolated into the message.

Source

Thrown at routes/history/history_routes.py:658

                "status": "ok",
                "id": new_id,
                "name": fork_name,
                "kept": len(msgs_to_copy),
            }
        except HTTPException:
            raise
        except Exception as e:
            logger.error(f"Fork error {session_id}: {e}")
            raise HTTPException(500, str(e))

    @router.get("/api/conversations/topics")
    async def get_conversation_topics(request: Request) -> Dict[str, Any]:
        from src.auth_helpers import require_user
        user = require_user(request)
        try:
            return analyze_topics(session_manager, owner=user or None)
        except Exception as e:
            raise HTTPException(500, f"Topic analysis failed: {e}")

    @router.get("/api/session/{session_id}/context")
    async def get_session_context_usage(request: Request, session_id: str) -> Dict[str, Any]:
        """Return an estimated whole-chat context usage for the session's model.

        Streaming footers report the prompt size for the last request. This
        endpoint estimates the persisted session context so the header can show
        when the whole chat is approaching compaction.
        """
        _verify_session_owner(request, session_id)
        try:
            session = session_manager.get_session(session_id)
        except KeyError:
            raise HTTPException(404, "Session not found")

        try:
            from src.model_context import estimate_tokens, get_context_length

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Read the server log / response body — '{e}' names the exact exception raised inside analyze_topics (src/topic_analyzer.py:21)
  2. Retry after all sessions finish hydrating; freshly restarted servers may expose transient half-loaded histories
  3. If one conversation triggers it, inspect that session's history for None/malformed messages
  4. Treat the topics view as best-effort: it is analytic, not transactional, so the app remains usable without it
Defensive patterns

Strategy: fallback

Try / catch

try { return await getTopics(); }
catch (e) { if (e.status === 500) return { topics: [] }; } // topics are best-effort analytics

Prevention

When it happens

Trigger: Opening the topics view when analyze_topics hits a message with unexpected content types, a session whose history contains None entries, a DB read error mid-iteration, or an owner filter that yields inconsistent cache state.

Common situations: Topics endpoint hit right after a restart with partially hydrated sessions; a conversation containing non-text content that the analyzer cannot process; auth disabled/enabled toggle changing the owner value passed in.

Related errors


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