pingdotgg / pingdotgg/t3code

Open in editor hangs forever when the server runs inside a Docker container reached over SSH

Open
#8,278 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
23k
Forks
5.9k
Avg merge
11h 14m
Merged PRs (30d)
357

Description

What happened

Open in editor doesn't work. My client is Cursor on a Mac, but the T3 server runs inside a VM-hosted Docker container that I reach with gcloud compute ssh --tunnel-through-iap into the VM followed by docker exec -it t3 bash. When I click Open in Cursor, Cursor launches on my Mac and shows "connecting" but the connection runs forever and never opens the workspace.

Diagnosis

The environment is classified as a remote SSH environment, so open-in-editor takes the remote-links path and hands the OS a deep link instead of exec'ing an editor on the server host:

cursor://vscode-remote/ssh-remote+<host><container-path>

built by buildRemoteOpenUrl (packages/contracts/src/editor.ts). This is confirmed by the server traces containing no shell.openInEditor RPC span for the attempts — in remote-links mode the deep link fires entirely client-side (openRemoteEditorUrl in apps/web/src/remoteOpen.ts) and never reaches the server.

The deep link can't ever connect, because ssh-remote+<host> can only address an SSH host, while the workspace lives inside a Docker container reachable only via ssh <VM> && docker exec:

  • Cursor/VS Code Remote-SSH connects to the VM, whose filesystem does not contain the container path (/workspace/repos/<project>), and
  • Remote-SSH cannot perform the docker exec hop, so it stalls bringing up the remote server / never lands on the right filesystem.

There is no ssh alias or advertised target that resolveRemoteOpenState / RemoteOpenTargets could carry that would open a containerized backend, so both open-in-editor strategies are dead ends for this topology:

  • remote-links → generates a link to the VM, which hangs (this report).
  • local-exec → would exec the editor inside the container, which has no editor on PATH, no DISPLAY, and is the wrong machine anyway.

RemoteOpenTargets.resolveTargets() (apps/server/src/environment/RemoteOpenTargets.ts) also advertises nothing here (no sshd on :22, no Tailscale), so even the direct-remote path has no route — but the failure the user sees is the ssh-alias deep link hanging, not the "No SSH route" dead-end.

Root gap: open-in-editor has no notion of a backend that lives inside a container behind an SSH host. A vscode-remote link would need the attached-container/dev-containers authority (…/attached-container+<hex>…) or an equivalent, not ssh-remote+<host>.

Steps to reproduce

  1. Run the T3 server inside a Docker container on a remote VM (npx t3 serve inside docker exec -it <container> bash); the VM is reached over SSH (here via gcloud compute ssh --tunnel-through-iap).
  2. Connect the T3 desktop app on a Mac to that server as a remote/SSH environment; have Cursor (or any Remote-SSH-capable editor) installed locally.
  3. Open a thread in a project whose workspace is a container path (e.g. /workspace/repos/<project>).
  4. Click Open-in-editor → Cursor.

Expected: Cursor opens the workspace on the Mac.
Actual: Cursor launches and hangs on "connecting" indefinitely; the workspace never opens. No shell.openInEditor span appears in server.trace.ndjson.

Version

0.0.34 (tag v0.0.34, latest stable)

Environment

Client: macOS, T3 desktop app (Electron), Cursor installed locally. Server: T3 0.0.34 in a Linux x64 Docker container (Node v24.19.0) on a GCP VM, reached via gcloud compute ssh --tunnel-through-iap + docker exec. Server bound to 127.0.0.1:8787.

Evidence

# Server host (the container): none of the routes open-in-editor relies on exist
$ ss -ltnp | grep ':22'        # -> no sshd
(no output)
$ command -v tailscale          # -> absent
$ command -v code cursor codium code-insiders zed   # -> none installed
$ ls /.dockerenv                # -> present (inside docker)
$ echo "$DISPLAY"               # -> empty (headless)

# RemoteOpenTargets therefore advertises nothing (RemoteOpenTargets.ts):
#   if (!sshdListening) return [];

# Clients on record (auth_sessions; credential columns omitted):
#   desktop  MacIntel  Electron   bearer-access-token   <- the failing client
#   desktop  macOS     Chrome     browser-session-cookie
#   mobile   iOS       Safari     browser-session-cookie

# Workspace roots are container paths (projection_projects):
#   /workspace/repos/<project>
#   /root/repos

# No server-side editor launch for the click:
$ grep -c 'shell.openInEditor' server.trace.ndjson*   # -> 0
#   (remote-links deep link fires client-side; never hits the server RPC)

Related issues

#7530 — same open-in-editor local-vs-remote subsystem, but a different failure: there a same-machine browser on a LAN IP is misclassified as remote and dead-ends at a disabled "No SSH route". This report is the opposite end — the environment is correctly remote, a deep link is generated, but ssh-remote+<host> cannot traverse into a Docker container, so it hangs. Not a duplicate.

Fix applied or workaround

Nothing was written to the machine (no DB writes, no source patches). Workaround: use Cursor's Dev Containers: Attach to Running Container — Remote-SSH into the VM, then attach to the t3 container and open the workspace folder. This is the only flow that crosses the docker exec boundary; T3's button cannot drive it.

Filed by

claude (Opus 4.8) via t3 triage

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading packages/contracts/src/editor.ts, apps/web/src/remoteOpen.ts, and apps/server/src/environment/RemoteOpenTargets.ts to trace remote-links and local-exec behavior. Reproduce the container-behind-SSH topology and define a supported open-in-editor path that reaches the container workspace without hanging, while preserving the existing direct SSH and local flows.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, electron, typescript
Domain
desktop, devops
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.