Skip to content

fix: prevent concurrent SSE connections from stalling in Firefox - #55386

Open
zonemeen wants to merge 1 commit into
anomalyco:devfrom
zonemeen:fix/sse-cache
Open

zonemeen wants to merge 1 commit into
anomalyco:devfrom
zonemeen:fix/sse-cache

Conversation

@zonemeen

@zonemeen zonemeen commented Oct 14, 2026 •

Copy link
Copy Markdown

Issue for this PR

Closes #55369

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Firefox can block a second tab's event stream while the first stream holds the same HTTP cache entry.

Fetch SSE streams with cache: "no-store" and return Cache-Control: no-store, no-transform from /api/event. Update the Promise client generator and regenerate the client. Ordinary requests retain their existing cache behavior.

How did you verify your code works?

  • Reproduced the hang in Firefox 148.0.2 using the actual client and server. After the fix, both tabs receive server.connected while remaining open.
  • Confirmed that changing the response header alone does not resolve the Firefox hang.
  • Added regression assertions for SSE request caching and response headers.
  • Server tests: 82 passed, 1 skipped.
  • Code generator tests: 98 passed.
  • Client tests: 225 passed, 4 failed. All four failures also reproduce on the unchanged base revision.
  • Root bun run check passed.

Screenshots / recordings

N/A — HTTP transport change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Added by the opencode bot (AI-generated).

Public API: /api/event now sends Cache-Control: no-store, and Promise client SSE requests use cache: "no-store" (backwards compatible)

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fixes the Firefox second-tab hang. I reproduced it with two Playwright Firefox tabs against opencode serve run from source, using the Promise client from each checkout. On the base, the second tab's event.subscribe() never got an event while the first stream was open. With this change it gets server.connected right away. The generator template and the committed client are in sync (check:generated shows no diff), and the changed packages pass their tests and type checks. The only client test failures, 2 of them, also fail on the base.

Public API impact, backwards compatible:

  • GET /api/event response header: Cache-Control: no-cache, no-transform → no-store, no-transform.
  • The generated Promise client's SSE methods now send cache: "no-store". Other requests are unchanged.

No existing callers need to change.

No blocking concerns.

This branch has not been deployed

No deployments
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.

web: second Firefox tab never connects to /api/event - Cache-Control: no-cache lets Firefox's HTTP cache block concurrent SSE requests

1 participant