Skip to content

fix: prevent 404 on /api/session/compress/status during session switch - #2185

Merged
1 commit merged into
nesquena:masterfrom
jasonjcwu:fix/compress-status-404
May 13, 2026
Merged

1 commit merged into
nesquena:masterfrom
jasonjcwu:fix/compress-status-404

Conversation

@jasonjcwu

Copy link
Copy Markdown
Contributor

Problem

Switching sessions in the sidebar triggers resumeManualCompressionForSession(), which calls GET /api/session/compress/status to check for active compression jobs. When no job is running (the common case), the route handler returned None (from j()) instead of True. In edge cases (stale process state, exception during response write), the do_GET fallback produced {"error":"not found"} with HTTP 404. The frontend then showed a "Compression failed: not found" toast on every session switch.

Fix

Backend (api/routes.py): handle_get now explicitly returns True after calling _handle_session_compress_status, ensuring the if result is False 404-fallback in do_GET can never trigger for this route.

Frontend (static/commands.js): resumeManualCompressionForSession catches 404 silently — no compression job means no error to surface. The early return in the catch block prevents the Compression failed toast.

Tests

6 regression tests in tests/test_compress_status_404_fix.py:

Test What it verifies
test_compress_status_returns_200_idle_for_unknown_session Idle case returns 200, not 404
test_compress_status_returns_200_idle_for_empty_session_id Empty SID returns 400 (bad)
test_handle_get_returns_true_for_compress_status handle_get returns True (not None)
test_handle_get_returns_true_for_compress_status_no_sid True even with missing SID (400 handled internally)
test_frontend_resume_404_silent Frontend catch block has e.status===404 guard with early return
test_frontend_compress_status_call_present API call path still present in frontend code

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

Reading api/routes.py:3195-3199 on the diff against origin/master, plus the master version of _handle_session_compress_status (api/routes.py:8068-8085) and server.py:242-258 for the 404 fallback, this is a tight two-line backend fix with a matching frontend guard.

Backend (api/routes.py:3195-3199)

if parsed.path == "/api/session/compress/status":
    query = parse_qs(parsed.query)
    _handle_session_compress_status(handler, query.get("session_id", [""])[0])
    return True

The reasoning checks out. _handle_session_compress_status always sends a response (via j() for idle/running/done or bad() for empty sid), but both helpers return None. handle_get previously bubbled that None to do_GET, where server.py:252-253 runs if result is False: return j(self, {'error': 'not found'}, status=404). None is False evaluates to False, so in the common path no 404 is emitted — but the description correctly flags the edge: any caller that converts the return value or any future refactor of that fallback to if not result would silently regress. Explicit return True matches the convention used by the kanban bridge (api/routes.py:3082-3089) and most other handlers.

Frontend (static/commands.js:484-491)

}catch(e){
  // 404 or network error during resume = no active compression job, not a real error
  if(e&&e.status===404) return;

The error shape comes from static/workspace.js:23-26, which sets err.status=res.status on every non-OK response, so the guard works. One minor concern: this only suppresses 404, not 5xx or network failures. If _handle_session_compress_status ever raises (e.g. _MANUAL_COMPRESSION_JOBS_LOCK deadlock during a session switch), do_GET's exception handler at server.py:254-256 emits a 500, and the user still gets a "Compression failed" toast on every switch. That's a different bug, not in scope here.

Tests

tests/test_compress_status_404_fix.py exercises the three branches I'd want pinned:

  • test_compress_status_returns_200_idle_for_unknown_session confirms the idle case is 200, not 404 (the visible symptom).
  • test_handle_get_returns_true_for_compress_status pins the contract that handle_get returns True, defending against the silent-None regression.
  • test_frontend_resume_404_silent source-greps for e.status===404 + early return.

The frontend assertion is a substring check, which is fragile to refactors but acceptable for this size of fix.

Verdict

LGTM. Minimal surface, defensive on both ends, tests pin the contract. Worth merging.

Optional follow-up (not blocking): the same defensive return True pattern would protect /api/wiki/status, /api/logs, /health, /api/health/agent, and similar single-call routes at api/routes.py:3091-3100 that currently return whatever j()/_handle_* returns. Most look fine in practice, but they share the same latent shape. Could be a one-line audit pass later.

Two-part fix:
- Backend: handle_get returns True (not None from j()) for compress/status
  route, preventing edge-case 404 fallback in do_GET
- Frontend: resumeManualCompressionForSession silently returns on 404
  instead of showing "Compression failed: not found" toast

Includes 6 regression tests covering backend return value, idle/empty
session responses, and frontend 404 guard presence.
@jasonjcwu
jasonjcwu force-pushed the fix/compress-status-404 branch from 759c263 to 9e45de4 Compare May 13, 2026 10:56
@jasonjcwu

Copy link
Copy Markdown
Contributor Author

Updated: broadened the frontend guard to also cover 5xx and network failures (!e.status), so a transient backend exception during session switch never surfaces the toast either. This addresses the 5xx concern you raised — the same reasoning applies: status check failure during resume is never user-actionable.

if(e&&(!e.status||e.status===404||e.status>=500)) return;

Agreed on the audit pass for other return j() routes — tracked for a follow-up.

@nesquena-hermes nesquena-hermes closed this pull request by merging all changes into nesquena:master in f5be6e3 May 13, 2026
pull Bot pushed a commit to TKaxv-7S/hermes-webui that referenced this pull request May 13, 2026
fix: prevent 404 on /api/session/compress/status during session switch (jasonjcwu)
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
fix: prevent 404 on /api/session/compress/status during session switch (jasonjcwu)
bernyforce pushed a commit to bernyforce/hermes-webui that referenced this pull request Jul 29, 2026
fix: prevent 404 on /api/session/compress/status during session switch (jasonjcwu)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants