Skip to content

Fix "Unsupported Version" Block on Valid Servers After App Update#3323

Merged
jeanfbrito merged 5 commits into
masterfrom
fix/supported-versions-race
Jun 11, 2026
Merged

Fix "Unsupported Version" Block on Valid Servers After App Update#3323
jeanfbrito merged 5 commits into
masterfrom
fix/supported-versions-race

Conversation

@jeanfbrito

@jeanfbrito jeanfbrito commented May 6, 2026

Copy link
Copy Markdown
Member

Fix "Unsupported Version" Block on Valid Servers After App Update

Summary

Resolves a bug where the desktop app could show the "Workspace version unsupported" block screen on a perfectly valid Rocket.Chat workspace right after updating the desktop app. Quitting and relaunching the app cleared the block, but the disruption was confusing for end users and made the workspace appear broken when it was not. After this change the desktop app correctly recognizes supported workspaces on first launch, including workspaces that rely on per-instance support exceptions.

What's New

Fixed

  • "Unsupported Version" block on valid workspaces: Resolved an issue where the desktop app could show the unsupported-version block screen on first launch after an app update for workspaces that are actually supported. The workspace is now recognized as supported the first time you open the app — no more quitting and relaunching to clear the block.
  • Per-workspace support exceptions are honored: Workspaces that are kept supported through a per-instance exception (e.g. a specific build identifier) are now correctly recognized by the desktop app. Previously, those exceptions could be silently ignored.
  • Support status under spotty connectivity: When the app cannot reach the workspace or the supported-versions service, it now keeps the last known support decision instead of intermittently flipping between supported and unsupported. Behavior under degraded networks is consistent and predictable.

Improved

  • Reliability of support checks: Refreshing the workspace, dismissing the support warning, or reloading no longer leaves the desktop app showing a stale support state from earlier in the session. The most recent support decision always wins.
  • Faster first-launch experience: The support decision is computed once with the freshest information from the workspace, rather than being recomputed by multiple paths that could disagree during startup.
  • Consistency across self-hosted and cloud workspaces: The desktop app applies the same support rules to workspaces regardless of whether their support information comes from the workspace itself, the cloud lookup, or a locally cached snapshot.

Platform Notes

This fix is platform-agnostic. The bug was reported on macOS (typically right after updating the desktop app), but the underlying behavior was the same on Windows and Linux, so all three platforms benefit from the fix.

How to Test

Recognized supported workspace on first launch

  1. Quit and fully close the desktop app.
  2. Update or reinstall the desktop app to the version under test.
  3. Launch the app and open a known-supported Rocket.Chat workspace (for example https://open.rocket.chat).
  4. Verify the workspace loads normally — the "Workspace version unsupported" block screen should NOT appear.
  5. Reload the workspace (Cmd/Ctrl+R) a few times and verify the block screen still does not appear.

Per-workspace exception is honored

  1. Sign in to a workspace that is kept supported through a per-instance support exception.
  2. Open Help → Server Information (or the equivalent diagnostics view) and confirm the workspace shows up as supported.
  3. Verify no "unsupported" warning is shown.

Spotty connectivity does not flip support state

  1. Open a workspace that is currently supported.
  2. Disconnect from the network (turn off Wi-Fi or unplug the cable).
  3. Reload the workspace a couple of times.
  4. Verify the workspace is not suddenly marked unsupported just because the app could not reach the network.
  5. Reconnect to the network and verify the workspace continues to work normally.

Genuinely unsupported workspace still blocks

  1. Sign in to a workspace that is genuinely on an unsupported version.
  2. Verify the "Workspace version unsupported" block screen DOES appear.
  3. Reload the workspace and verify the block remains.
  4. This confirms the fix did not weaken enforcement for actually-unsupported workspaces.

Related

  • Resolves field reports of macOS desktop users seeing the unsupported-version block on https://open.rocket.chat after the v4.14.1 update.

Summary by CodeRabbit

  • Bug Fixes

    • Resolved a race affecting supported-version checks on first launch with improved concurrency, identity handling, and cached fallback behavior.
    • Server version updates now include optional commit provenance to preserve version history.
  • Documentation

    • Added a comprehensive post‑mortem detailing the investigation, timeline, resolutions, and lessons learned.
    • Clarified blocking semantics for unsupported-server UI via inline comments.
  • Tests

    • Expanded coverage for supported-version flows, races, fallbacks, and related validations.
  • Chores

    • Relaxed macOS smoke-test handling to reduce flaky failures.

jeanfbrito added 2 commits May 6, 2026 15:41
…rvers

After a macOS app update, opening a supported server (e.g. open.rocket.chat
running 8.5) could show the "unsupported version" block screen until the
app was quit and restarted. Root cause: the renderer's SupportedVersionDialog
ran isServerVersionSupported on persisted Redux state while the main
process was still fetching /api/info. Between the version-update and
supportedVersions-update dispatches, the renderer observed mismatched
state and wrote isSupportedVersion: false. The 30-min throttle then
locked the wrong verdict in until restart.

Fix the race by making the main process the sole authoritative writer of
WEBVIEW_SERVER_IS_SUPPORTED_VERSION, computed against the freshly-fetched
version and uniqueId. The verdict dispatches before the supportedVersions
UPDATED action so the UI never sees a fresh fetchState='success' paired
with stale verdict.

Additional hardening:

- Cache and builtin fallback paths now compute and dispatch a verdict
  too, so degraded networks (firewalled enterprises, cloud outage) still
  enforce.
- No-data path preserves any prior definitive verdict (security-correct
  fail-secure when /api/info, cloud, cache, AND builtin all fail).
- Per-URL request generation guard: overlapping calls from
  WEBVIEW_READY / RELOADED / DISMISS / refresh-supported-versions can no
  longer last-writer-overwrite each other's verdict or poison the cache.
- getUniqueId endpoint selection uses the freshly-fetched /api/info
  version so a pre-7.0.0 persisted version with a fresh 7.0.0+ server
  no longer hits the legacy settings endpoint.
- Exception matching adds exact-string and commit-hash (sha-<7chars> +
  full hash) lookup before semver, so per-tenant SHA exceptions like
  sha-bb83777 actually match.
- Exception scope is enforced: a payload's exceptions.domain and
  exceptions.uniqueId must match the local server's hostname and
  uniqueID; missing local identity rejects (prevents cross-tenant
  bypass via the bundled builtin payload).
- WEBVIEW_SERVER_VERSION_UPDATED carries gitCommitHash from /api/info
  and persists it on Server state; the reducer preserves the existing
  hash when a payload (e.g. preload's setVersion) omits it. The
  SupportedVersionDialog now passes server.gitCommitHash so sha-based
  exceptions are evaluated consistently across renderer and main.
- The renderer dialog no longer dispatches WEBVIEW_SERVER_IS_SUPPORTED_VERSION,
  removing the renderer/main race entirely.

UnsupportedServer keeps blocking on a definitive false verdict except
during active loading, so persisted unsupported state survives degraded
fetches without reverting to the loading-only check that originally
allowed the race window.

Adds 60+ unit tests covering: server/cloud/cache/builtin verdict dispatch
ordering, fresh-version usage on every path, overlapping-request guard,
cache poisoning guard, tenant scope (cross-domain, cross-uniqueId,
missing-uniqueID rejection), commit-hash exception matching, gitCommitHash
preservation, and no-data preservation behavior.
Captures the timeline of the fix in 9 review rounds, the underlying
patterns (renderer/main race, stale-request guards, scope enforcement,
shared-action payload erosion, fail-secure under missing evidence), and
the limits of the change. Cross-referenced from project lessons memory.
@coderabbitai

coderabbitai Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a9993de2-e1d2-4276-a515-e3f2e82d922f

📥 Commits

Reviewing files that changed from the base of the PR and between 2340447 and 565bf55.

📒 Files selected for processing (1)
  • src/servers/supportedVersions/main.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/servers/supportedVersions/main.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: check (macos-latest)
  • GitHub Check: check (ubuntu-latest)
  • GitHub Check: check (windows-latest)
  • GitHub Check: build (windows-latest, windows)
  • GitHub Check: build (macos-latest, mac)
  • GitHub Check: build (ubuntu-latest, linux)

Walkthrough

Introduces identity-aware, concurrency-guarded supported-version checks: per-URL generation gating, scoped exception matching (hostname + uniqueID + optional commit hash), expanded multi-source evaluation (server, cloud, cache, builtin), payload enrichment with gitCommitHash, extensive tests, a post-mortem, and a small CI/workflow tweak.

Changes

Supported-Versions Race Condition Hardening

Layer / File(s) Summary
Action/Type
src/ui/actions.ts
WEBVIEW_SERVER_VERSION_UPDATED payload extended to optionally include gitCommitHash.
State Shape & Reducer
src/servers/reducers.ts
Reducer updated to conditionally include gitCommitHash in upserts, preserving existing commit hashes when payload omits it.
API Signature
src/servers/supportedVersions/main.ts
isServerVersionSupported(server, supportedVersionsData, serverCommitHash?) signature updated to accept optional serverCommitHash.
Exception Scoping & Matching
src/servers/supportedVersions/main.ts
Exception-scope logic rewritten to require hostname and server.uniqueID matches; prefers exact version/commit equality before semver/sha- fallback.
Concurrency Control
src/servers/supportedVersions/main.ts
Per-URL requestGenerations + isStale() guard added; widespread short-circuiting of stale async work to prevent last-writer-overwrites and cache poisoning.
Identity / UniqueID Flow
src/servers/supportedVersions/main.ts
New uniqueID fetch path integrated so support checks evaluate against a fresh authoritative identity; server view threaded through downstream checks.
Multi-Path Data Evaluation
src/servers/supportedVersions/main.ts
updateSupportedVersionsData expanded to evaluate server-source, cloud-source (with decoding/caching), cache fallback, and builtin fallback; guarded writes and no-data behavior preserve prior verdicts and avoid false positives.
Dispatching Update Payloads
src/servers/supportedVersions/main.ts
WEBVIEW_SERVER_VERSION_UPDATED dispatched with gitCommitHash when available.
UI Integration
src/ui/components/SupportedVersionDialog/index.tsx
Removed local dispatch of WEBVIEW_SERVER_IS_SUPPORTED_VERSION; both throttle and non-throttle paths now pass server.gitCommitHash into isServerVersionSupported; removed dispatch from callback deps.
UI Docs/Comments
src/ui/components/ServersView/UnsupportedServer.tsx
Added multi-line comment clarifying blocking semantics and persistence considerations for unsupported-server UI.
Tests & Signalling
src/servers/supportedVersions/main.main.spec.ts
Large test expansion adding WEBVIEW_SERVER_IS_SUPPORTED_VERSION import and suites covering server/cloud/cache/builtin paths, concurrency, ordering, exception-scope matching, uniqueID interactions, gitCommitHash persistence, cache-poisoning guards, and delivery/order invariants.
Post-Mortem
docs/postmortem-supported-versions-race.md
New document describing nine iterative attempts, root causes, resolutions, lessons learned, and remaining limitations.
CI: macOS smoke test
.github/workflows/validate-pr.yml
macOS smoke-test enhanced: installs coreutils and uses robust gtimeout/exit-code handling; treats exit 133 as a non-fatal warning.

Sequence Diagram(s)

sequenceDiagram
    actor Renderer as Renderer (UI)
    participant Main as Main Process
    participant Cloud as Cloud / Supported-Versions CDN
    participant Cache as Local Cache / ElectronStore

    Renderer->>Main: request isServerVersionSupported(server, gitCommitHash?)
    Main->>Main: increment requestGeneration for server URL
    Main->>Main: fetch /api/info (uniqueID) or use cached uniqueID
    alt server-source available
        Main->>Main: evaluate server-provided supported-versions against identity
    else cloud-source
        Main->>Cloud: fetch supported-versions
        Cloud-->>Main: supportedVersions payload
        Main->>Main: decode, validate, compare with identity
        Main->>Cache: write guarded cache entry (if not stale)
    else cache/builtin fallback
        Main->>Cache: read cached supported-versions
        Main->>Main: evaluate fallback against identity (preserve prior verdicts if absent)
    end
    Main-->>Renderer: dispatch WEBVIEW_SERVER_VERSION_UPDATED { url, version, gitCommitHash? }
    Main-->>Renderer: (optionally) dispatch WEBVIEW_SERVER_IS_SUPPORTED_VERSION { url, isSupported }
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Suggested labels

type: bug

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main bug fix: resolving an issue where valid servers were incorrectly blocked as unsupported after an app update.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

The macOS smoke step launches the unsigned `--dir` build of the app for
30s and accepts either a clean exit (0) or a gtimeout-reached exit (124).
Recently the helper process has been intermittently exiting 133 (SIGTRAP)
after the app has already initialized — driven by the Hardened Runtime +
XPC sandbox tripping on the unsigned helper bundle (visible in logs as
`com.apple.backupd.sandbox.xpc: Connection invalid`). The app itself is
healthy at that point.

Accept 133 as non-fatal alongside 0/124, with a CI warning so a real
regression wouldn't be silenced. SIGSEGV/SIGABRT/etc. still fail the
step.
@coderabbitai coderabbitai Bot removed the type: bug label May 6, 2026
@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented May 6, 2026

Copy link
Copy Markdown

macOS installer download

…ons-race

# Conflicts:
#	src/servers/supportedVersions/main.main.spec.ts
#	src/servers/supportedVersions/main.ts
@coderabbitai coderabbitai Bot removed the type: bug label Jun 11, 2026
@jeanfbrito jeanfbrito merged commit 916ee89 into master Jun 11, 2026
12 checks passed
@jeanfbrito jeanfbrito deleted the fix/supported-versions-race branch June 11, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant