Skip to content

Echo-suppression breaks across reload when sessionStorage is unavailable (clientId regenerates) #501

Description

@lindkvis

Summary

In a private window or when sessionStorage is unavailable/disabled, the per-tab clientId regenerates on every page reload, which breaks WebSocket echo-suppression across a reload: in-flight events for a mutation issued before the reload carry the old origin_client_id, no longer match, and are treated as external — so the user can see a pill for their own pre-reload change.

Root cause

resolveClientId() (frontend/src/stores/useWsStore.js:11-36) reads/writes sessionStorage["pixlstash:clientId"] inside try/catch (correctly logged, no silent swallow). When the write throws, the id is in-memory only and is regenerated on the next reload (:27-35). The mismatch is then detected at useGridRealtimeSync.js:274.

This is narrow and environment-gated — in normal browsers the id is stable for the tab's lifetime, and no mutating request path bypasses the X-Client-Id header (verified: single axios client, no mutating raw fetch). Lower priority than the dropped-origin and coalescing defects.

Reproduction

Manual (Phase 3 checklist): open a private window, perform a tag/score edit, reload immediately, observe whether a pill appears for the just-made change. No automated spec yet (Playwright contexts have working storage).

Fix direction

Fall back to a longer-lived identifier (e.g. derive from an existing stable signal) or accept the limitation and document it. Low priority.

Full analysis: docs/reviews/2026-06-grid-refresh-cleanup-plan.md §7.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingjavascriptPull requests that update javascript code

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions