Skip to content

[Bug]: Remote environments stay switched off after a protocol mismatch, even once the host is updated #15051

Description

@vitalyiegorov

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

Not sure

Steps to reproduce

  1. Update the client to a release with a new orchestration protocol (here feat(orchestrator): introduce new orchestrator #2829, 0.0.46-nightly.20261003.2610). A saved T3 Connect host, switched on, is still on the old protocol. Its row shows Client not supported.
  2. Update the host to the same release.
  3. Look at Settings → Connections, with or without relaunching the client.

Expected behavior

The environment reconnects once its host is compatible. The user never switched it off.

Actual behavior

It stays Off (tooltip: Switched off), and its threads disappear until the user notices and turns it back on by hand.

Cause

setCompatibility in packages/client-runtime/src/connection/registry.ts writes an incompatible environment into the user's persisted switched-off list (registrations.setEnabled(id, false)). The reason (unsupportedReason) is kept only in memory. When a fresh check clears it, or after a relaunch, the entry is indistinguishable from one the user switched off, so nothing turns it back on.

Suggested fix

Treat compatibility as runtime state. Keep setting unsupportedReason and disconnecting, but stop changing enabled or the persisted list. Connect only when enabled && !unsupportedReason, and reconnect when the block clears. An environment the user switched off stays off. I can open the PR.

Impact

Major degradation or frequent failure

Version or commit

t3@0.0.46-nightly.20261003.2610 (main 8283b48)

Environment

macOS desktop client. Hosts: macOS (launchd) and Linux (systemd) services over T3 Connect.

Screenshots, recordings, or supporting files

Both hosts updated to the same nightly with relay tunnels registered. The client still shows them switched off:

Both saved environments stuck at T3 Connect · Off after their hosts were updated

Workaround

Turn each environment back on in Settings → Connections.

Related

Activity

  1. juliusmarminge commented on Oct 3, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Triage

    Thanks for the write-up, @vitalyiegorov. This is a real bug, and it's separate from #14979.

    What's wrong: EnvironmentRegistry.setCompatibility records a protocol rejection as if the user had switched the environment off. When a saved environment is on, it sets enabled: false and calls registrations.setEnabled(id, false), which writes to the persisted switched-off list. unsupportedReason lives only in memory. When a later compatible health check calls setCompatibility(id, null), only the reason is cleared: enabled stays false and nothing reconnects. After a relaunch the reason is gone, so the row shows Off with the Switched off tooltip. That's the same thing @michft described on #14979 once both hosts were on the same nightly.

    The merged #11990 added this to stop an incompatible server from sitting in a retry loop. Holding the connection off while the host is old makes sense, but it shouldn't become the saved state once the host is compatible again. The in-app update flow already recovers, because outdatedHostUpdate clears the block and then calls setEnabled(true). A host updated on its own (launchd, systemd, or a manual upgrade) never goes through that path, so its threads stay hidden until someone notices the switch.

    Intended behavior: compatibility should be runtime state, not a saved setting.

    • While the protocol doesn't match, keep unsupportedReason, disconnect, and show Client not supported with the switch disabled. That should apply to both relay discovery and a socket preflight rejection.
    • Leave enabled and the persisted switched-off list untouched for that block, so an environment the user turned off stays off.
    • When a fresh check clears the block, reconnect if enabled is still true. Discovery should still ignore a replayed health result, so an older relay snapshot can't clear a newer socket rejection.
    • Only reconnect when the block is cleared, so a host that's still on an old build doesn't loop.

    Fix scope: the packages/client-runtime registry, plus the registry tests that currently expect the opposite. One trap: setEnabled(true) returns early when enabled is already true. Once the block stops flipping enabled, setCompatibility(null) has to connect an enabled environment itself, or the in-app update flow stops resuming.

    Rows that were already saved as switched off will stay off. They have no stored reason, so they can't be told apart from a real user toggle, and on those machines the workaround is still to switch each environment back on once.

    #14979 covers the dark-mode switch contrast, which the open PR #14984 addresses. This issue covers environments that stay off after the host becomes compatible again. A maintainer will decide on the fix direction.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 3, 2026
  3. added 3 commits that reference this issue on Oct 3, 2026
    812322d
    a96277c
    50edad5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions