Repository navigation
T3 Code Desktop 0.0.23 fails SSH environment pairing due to DateTime schema mismatch #2665
Description
Activity
I can reproduce the same issue on macOS with T3 Code Desktop 0.0.23.
Environment:
- App: T3 Code (Alpha)
- Version: 0.0.23
- OS: macOS
- Remote host: Ubuntu VPS
- Remote T3 server:
t3 v0.0.23 - Flow: Settings -> Connections -> Remote Environments -> Add environment -> SSH launch
Error:
Error invoking remote method 'desktop:bootstrap-ssh-bearer-session': DesktopSshRemoteApiError: SSH remote API request failed during bootstrap-bearer-session. Desktop trace shows the same schema failure: SchemaError: Expected DateTime.Utc, got "2026-06-13T02:48:40.149Z" at ["expiresAt"] Important detail: SSH and the tunnel were working. The remote server received the request through the local forwarded port and returned HTTP 200 for: POST /api/auth/bootstrap/bearer Remote trace showed: http.response.status_code: 200 http.response.header.content-type: application/json The response shape was: { "authenticated": true, "role": "client", "sessionMethod": "bearer-session-token", "expiresAt": "2026-06-13T02:48:40.149Z", "sessionToken": "..." } So this is not an SSH auth/tunnel failure. It is the desktop app rejecting a valid JSON response because expiresAt is decoded with Schema.DateTimeUtc instead of a JSON-string decoder like Schema.DateTimeUtcFromString. I also verified a workaround: running the remote T3 server manually on the VPS loopback interface and using a normal SSH LocalForward plus pairing URL works, because it avoids the desktop-managed SSH bearer bootstrap path.Opened a small PR for this: #2694
The issue is a schema/wire-format mismatch: auth timestamps arrive as ISO strings over HTTP JSON, but the desktop decoder expected DateTimeUtc. The PR switches those auth response fields to DateTimeUtcFromString.
Tested locally, and SSH pairing works now.
I can confirm this still reproduces with T3 Code Desktop / CLI
0.0.24on Fedora 43 using an SSH remote environment.Setup:
- Workstation: Fedora 43, T3 Code Desktop installed from the
0.0.24AppImage - Remote VM: Fedora 43,
t3 v0.0.24installed via npm, launched by the desktop SSH remote flow - Remote server: managed by desktop on
127.0.0.1:3773
Desktop error:
Error invoking remote method 'desktop:bootstrap-ssh-bearer-session': DesktopSshRemoteApiError: SSH remote API request failed during bootstrap-bearer-session. (local http://127.0.0.1:<port>/, remote port 3773, remote server managed)The SSH tunnel and remote API were actually working. The desktop trace showed the real failure while decoding the successful bearer bootstrap response:
SchemaError: Expected DateTime.Utc, got "2026-06-20T17:27:37.815Z" at ["expiresAt"]After patching the remote bundle to remove fractional seconds, it still failed with:
SchemaError: Expected DateTime.Utc, got "2026-06-20T17:33:06Z" at ["expiresAt"]As a local workaround, I patched the remote
t3bundle to serializeexpiresAtas Effect DateTime JSON instead of an ISO string:const toDateTimeUtcJson = (value) => ({ "~effect/time/DateTime": "~effect/time/DateTime", _tag: "Utc", epochMilliseconds: DateTime.toEpochMillis(DateTime.toUtc(value)), });
and used that for the bearer bootstrap response. After restarting the managed remote server, adding the SSH remote worked.
That matches the diagnosis here: the desktop client is decoding HTTP JSON response fields with
Schema.DateTimeUtceven though the remote server sends normal JSON ISO date strings. The proper fix seems to be the one in #2694: decode those HTTP response timestamps withSchema.DateTimeUtcFromString.- Workstation: Fedora 43, T3 Code Desktop installed from the
Confirming this still reproduces on 0.0.24 (latest npm
latesttag).Environment
- Desktop: T3 Code (Alpha)
0.0.24on macOS - Remote: Ubuntu 24.04 VPS, Node
v24.15.0(from NodeSource),t3@0.0.24installed vianpx - Flow: Option 3 — Desktop-Managed SSH Launch
Symptom (identical to the original report)
The remote server starts cleanly, runs all 30 migrations, listens on127.0.0.1:3773, and prints a valid pairing URL. The desktop opens the SSH forward, issues a pairing token viat3 auth pairing create --json, and POSTs{"credential":"<token>"}to/api/auth/bootstrap/bearer. The server responds HTTP 200 with a well-formed payload:{ "authenticated": true, "role": "client", "sessionMethod": "bearer-session-token", "expiresAt": "2026-06-25T16:27:53.081Z", "sessionToken": "eyJ..." }The desktop then fails to decode the response. From
~/.t3/userdata/logs/desktop.trace.ndjson:SchemaError: Expected DateTime.Utc, got "2026-06-25T16:27:53.081Z" at ["expiresAt"]The error surfaces in the UI as:
Error invoking remote method 'desktop:bootstrap-ssh-bearer-session': DesktopSshRemoteApiError: SSH remote API request failed during bootstrap-bearer-session.Why other flows are not affected
The strict decode is unique to the SSH path.DesktopSshRemoteApi.bootstrapBearerSessionruns the JSON body throughSchema.decodeUnknownEffect(AuthBearerBootstrapResult), while the LAN / Tailscale / Remote pairing path (apps/web/src/environments/remote/api.ts) doesreturn (await response.json()) as T;and skips schema validation, so the ISO string forexpiresAtslips through unchecked. That is why this bug only manifests through Option 3.Verified workaround (no patching required)
Skip Option 3 and use Option 2 instead:- Start the server manually on the remote:
npx -y t3@0.0.24 serve --host <tailnet-ip> --base-dir ~/.t3 - Copy the printed pairing URL.
- In the desktop, Add environment → paste pairing URL (not the SSH launch flow).
That path uses the non-schema-validated remote pairing code and connects without issue. The remote server still does the heavy lifting; only the bootstrap-bearer-session IPC step is bypassed.
The fix suggested in the original report (
Schema.DateTimeUtc→Schema.DateTimeUtcFromStringfor fields decoded from HTTP JSON) still looks like the right resolution — happy to test a patched build if a draft PR shows up.- Desktop: T3 Code (Alpha)
I've experienced the same issue on 0.0.23 (holding off on upgrading until patched). I was able to correct it with a patch like #2694 I hope we can get this fixed soon.
Still reproduces on desktop 0.0.24 (Linux AppImage) connecting to a remote
t3@0.0.24server over SSH launch. Same root cause as reported for 0.0.23.The remote server starts fine and the loopback tunnel works:
INFO (#191): Listening on http://127.0.0.1:3773…but bootstrap fails on the desktop:
Error invoking remote method 'desktop:bootstrap-ssh-bearer-session': DesktopSshRemoteApiError: SSH remote API request failed during bootstrap-bearer-session. [cause]: SchemaError: Expected DateTime.Utc, got "2026-06-27T21:07:51.808Z" at ["expiresAt"]Confirmed in isolation with the bundled
effect@4.0.0-beta.59thatSchema.DateTimeUtcrejects every
JSON-serializable shape, so no server response can satisfy the currentAuthBearerBootstrapResultdecoder:import { Schema } from "effect"; const dec = Schema.decodeUnknownSync(Schema.DateTimeUtc); dec("2026-06-27T21:07:51.808Z"); // throws: Expected DateTime.Utc, got "..." dec(1782680871808); // throws dec(1782680871); // throws // Schema.DateTimeUtcFromString is the correct wire codec (as in #2694)
PR #2694 (
DateTimeUtc→DateTimeUtcFromStringforexpiresAt/issuedAt/createdAt/lastConnectedAt)
fixes this. Requesting a merge + a stable release that includes it — remote SSH is currently unusable on
the latest stable build without running a fork/patch. Thanks!yeah, i have the same issue. i'm connecting to a remote server. i'm on desktop 0.0.24 (macOS Tahoe)
Summary
T3 Code Desktop
0.0.23on Windows fails when adding an SSH environment because the desktop app decodes JSON API timestamp strings withSchema.DateTimeUtcinstead ofSchema.DateTimeUtcFromString.This causes SSH bearer session bootstrap to fail even though the remote T3 server returns HTTP 200 with a valid JSON response.
Environment
0.0.23Error