Skip to content

fix: recover wrong-pod actions instead of 404 (action/SSE symmetry)#123

Merged
joaomdsg merged 1 commit into
mainfrom
fix/action-404-cross-pod
Jun 10, 2026
Merged

fix: recover wrong-pod actions instead of 404 (action/SSE symmetry)#123
joaomdsg merged 1 commit into
mainfrom
fix/action-404-cross-pod

Conversation

@joaomdsg

Copy link
Copy Markdown
Member

Top item from the 1.0 design council: the only remaining cross-pod correctness gap.

Problem

An action POST whose via_tab this pod doesn't hold returned a bare 404 — silently dropping the click — while the SSE handshake already re-bootstraps the same stale tab (recoverSSE). Without sticky sessions, an action round-robined to the wrong pod just died, with no recovery and no feedback. SSE recovers; actions didn't — a strictly-worse asymmetry.

Fix

A recoverable id (well-formed and naming a mounted route — wrong-pod routing, TTL sweep, or restart) now gets a reload directive over the datastar action response (reusing streamReloadScript, the SSE path's degraded-recovery), so a fresh page GET re-bootstraps the tab. The descriptor's group middleware runs first (auth vetoes recovery as it vetoes the page); a forged id (no mounted route) keeps the historical 404 so junk can't mint contexts. Emits via.action.recover{mode=reload} (added to the metrics catalogue).

Tests

  • recoverable unknown tab → 200 + location.reload script + via.action.recover metric (not 404)
  • forged tab (no mounted route) → still 404

Full ci-check.sh green.

An action POST whose via_tab this pod doesn't hold returned a bare 404 —
silently dropping the click — while the SSE handshake already re-bootstraps the
exact same stale tab (recoverSSE). Without sticky sessions an action routed to
the wrong pod thus died with no recovery, the only remaining cross-pod
correctness asymmetry.

A recoverable id (well-formed and naming a mounted route — wrong-pod routing, a
TTL sweep, or a restart) now gets a reload directive over the datastar action
response, so a fresh page GET re-bootstraps the tab — the same degraded-recovery
path the SSE handshake uses. The descriptor's group middleware runs first so an
auth guard vetoes recovery exactly as it vetoes the page, and a forged id (no
mounted route) keeps the historical 404 so junk traffic still can't mint
contexts. Emits via.action.recover{mode=reload}.
@joaomdsg
joaomdsg merged commit bb00640 into main Jun 10, 2026
6 checks passed
@joaomdsg
joaomdsg deleted the fix/action-404-cross-pod branch June 10, 2026 21:14
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.

1 participant