Skip to content

T3 Connect fails with “Relay has no active link” when the server is linked to a previous account #21857

Open

Description

@jizoquval

What happened

I want to use one Mac as a T3 Code server (background service) and reach it with T3 Connect from a second Mac. Both Macs were signed into the same T3 Connect account. On the second Mac (desktop app), clicking connect on the server environment failed with:

Connection failed: Relay has no active link for this environment. If it was deregistered from T3 Connect, link it again on that machine.

The server Mac had previously been linked to T3 Connect with a different account.

Diagnosis

The server environment still held the stored link (CLOUD_LINKED_USER_ID) for the previous account, while the CLI on that machine was authorized with the new account. On every service start, reconcileDesiredCloudLinkWith gets a new link from the relay for the new account, then applyCloudRelayConfig → validateLinkedCloudUser (apps/server/src/cloud/CloudLink.ts:597-613 at v0.1.0) sees a different stored user id and fails with CloudLinkAccountMismatchError. server.ts handles this by logging a warning (Failed to reconcile T3 Connect desired link on startup) and carrying on. The relay never gets an active link for the environment, so clients get the "no active link" error.

The guard itself is reasonable (don't switch accounts silently), but the user can't see the failure anywhere:

  • The client shows the generic "no active link / deregistered" text (packages/client-runtime/src/relay/errorPresentation.ts:44), which points away from the real cause. The suggested remedy, "link it again on that machine", also doesn't work: linking keeps hitting the same mismatch until the old link is removed.
  • t3 connect status --json on the server reported "authenticated": true, "linked": true, with the old account's cloudUserId. It gave no sign that the link belongs to a different account than the current CLI authorization, or that reconciliation keeps failing.
  • The only trace is a WARN line in boot-service.log and failed spans in server.trace.ndjson.

The client message and the startup handling are unchanged on main as of 2026-10-17.

Suggested improvements (any of these would have pointed straight at the fix):

  1. Have t3 connect status (and the T3 Connect settings UI) report an account mismatch between the stored link and the current CLI authorization, and suggest t3 connect unlink then t3 connect link.
  2. Have t3 connect link detect the mismatch up front and offer to unlink the old account.
  3. If the relay/server can tell, have the connecting client say the host is linked to a different account instead of "no active link".

Steps to reproduce

  1. On machine A, sign in to T3 Connect with account X and link the environment (background service via t3 service).
  2. On machine A, authorize the CLI with a different account Y (t3 connect login, then t3 connect link) without running t3 connect unlink first.
  3. Restart the service (t3 service restart). boot-service.log shows Failed to reconcile T3 Connect desired link on startup { cause: { _tag: 'CloudLinkAccountMismatchError' } }.
  4. On machine B, signed into account Y, connect to machine A's environment → "Relay has no active link for this environment".

Version

0.1.0 (server: background service t3@0.1.0; client: desktop app 0.1.0)

Environment

Server: macOS 26 (Darwin 25.5.0) arm64, Node v24.21.0, launchd background service, . Client: second Mac, desktop app 0.1.0.

Evidence

# boot-service.log (server, at service start)
[19:58:50.188] INFO (#4633): agent activity publishing enabled
  { relayUrl: 'https://relay.t3.codes' }
[19:59:05.727] WARN (#4651): Failed to reconcile T3 Connect desired link on startup
  { cause: { _tag: 'CloudLinkAccountMismatchError' } }

# server.trace.ndjson (repeats for environment.cloud.reconcileDesiredLinkWith,
# reconcileDesiredLinkIfStillDesired, relayConfig)
CloudLinkAccountMismatchError: This environment is already linked to a different cloud account. Unlink it before switching accounts.
    at environment.cloud.applyRelayConfig
    at environment.cloud.reconcileDesiredLinkWith
    at environment.cloud.reconcileDesiredLinkIfStillDesired

# t3 connect status --json (before fix; the cloudUserId was the OLD account)
"desired": true, "authenticated": true, "linked": true, "revoked": false,
"cloudUserId": "user_<old account>", "relayUrl": "https://relay.t3.codes"

Related issues

#19069 (closed): same client message, but the cause there was a deregistered environment that never relinked; fixed in #19379. Here the environment can't relink because of a stored account mismatch that nothing surfaces. #6568 is a different relay failure (endpoint_provider_not_managed).

Fix applied or workaround

On the server machine:

t3 connect unlink      # clears the stale link to the old account, keeps current authorization
t3 connect link
t3 service restart

After this, t3 connect status showed linked: true with the new account, the managed tunnel registered, and the second Mac connected. Note: unlink also set publishAgentActivity to false, so the user has to re-enable it with t3 connect publish.

Filed by

Claude Code (claude-opus-5-5) via t3 triage

Activity

  1. juliusmarminge commented on Oct 19, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Thanks for the precise trace. Current main matches it.

    The account guard is intended. A stored link for a different account fails with a clear message telling you to unlink first (apps/server/src/cloud/CloudLink.ts:174-180, :544-561). That message just never reaches you on this path:

    • At startup the failure is only logged as a warning (apps/server/src/server.ts:1003-1007).
    • t3 connect link only saves that the link is wanted. It doesn't compare against the stored account (apps/server/src/cli/connect.ts:521-547).
    • t3 connect status reports linked whenever any stored account id exists (connect.ts:579-584).
    • The connecting client shows the generic "no active link" text (packages/client-runtime/src/relay/errorPresentation.ts:44).

    Accepting this as a bug in how the mismatch is reported, not in the guard itself.

    For now, running t3 connect unlink, then t3 connect link, then restarting the service clears it. Unlinking also turns off agent activity publishing, so turn that back on afterwards if you use it.

  2. added
    acceptedfeature request accepted
    bugSomething is broken or behaving incorrectly.
    on Oct 19, 2026
  3. juliusmarminge commented on Oct 22, 2026

    @juliusmarminge
    Member

    Fresh triage at b5a226e49c: this remains an ordinary bug report; it does not describe an exploitable vulnerability. No duplicate found in the open-issue scan covering the last 90 days.

    Real-app reproduction was blocked before step 1: this Linux triage environment has no supplied pair of authorized T3 Connect test accounts. The reported macOS service / second-Mac desktop sequence was not run, and source inspection is not reproduction.

    Verification still needs the two-account sequence on current main, with redacted t3 connect status --json output and the startup reconciliation warning. Do not post credentials or tokens. No fix or PR was made; the intended account guard is unchanged. Maintainer-assisted verification is needed.

  4. added
    needs more infoInitial triage showed no bug. Awaiting more info
    and removed
    needs more infoInitial triage showed no bug. Awaiting more info
    on Oct 22, 2026
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

    acceptedfeature request acceptedbugSomething 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