Repository navigation
T3 Connect fails with “Relay has no active link” when the server is linked to a previous account #21857
Description
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 --jsonon the server reported"authenticated": true, "linked": true, with the old account'scloudUserId. 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.logand failed spans inserver.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):
- Have
t3 connect status(and the T3 Connect settings UI) report an account mismatch between the stored link and the current CLI authorization, and suggestt3 connect unlinkthent3 connect link. - Have
t3 connect linkdetect the mismatch up front and offer to unlink the old account. - 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
- On machine A, sign in to T3 Connect with account X and link the environment (background service via
t3 service). - On machine A, authorize the CLI with a different account Y (
t3 connect login, thent3 connect link) without runningt3 connect unlinkfirst. - Restart the service (
t3 service restart).boot-service.logshowsFailed to reconcile T3 Connect desired link on startup { cause: { _tag: 'CloudLinkAccountMismatchError' } }. - 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 restartAfter 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
juliusmarminge commentedon Oct 19, 2026
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:apps/server/src/server.ts:1003-1007).t3 connect linkonly saves that the link is wanted. It doesn't compare against the stored account (apps/server/src/cli/connect.ts:521-547).t3 connect statusreports linked whenever any stored account id exists (connect.ts:579-584).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, thent3 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.juliusmarminge commentedon Oct 22, 2026
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 --jsonoutput 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.