Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
Build, CI, or release tooling
Steps to reproduce
- Run T3 Code as a server on the default port 3773 (for example, the background service, whose env sets
T3CODE_PORT=3773, and possiblyT3CODE_HOSTorT3CODE_LAN=truefromservice.env). - In a thread, have the agent (Claude, Codex, or another provider) open a shell in a T3 Code checkout or worktree. Its env contains the server's own
T3CODE_PORT=3773(andT3CODE_HOSTandT3CODE_LAN, if set), because provider processes inherit the server's environment. - From that shell, run
node scripts/dev-runner.ts dev:server --dry-run(orvp run dev).
Expected behavior
The dev runner uses the port it derives from the worktree path (or T3CODE_PORT_OFFSET / T3CODE_DEV_INSTANCE, the documented selectors), binds the way a fresh dev server would, and honours only an explicit --port or --host.
Actual behavior
The dev runner picks up the live server's port and network config:
[dev-runner] mode=dev:server source=worktree <worktree> serverPort=3773 ...
vp run devthen collides with the live server on 3773. Because the port counts as explicit, the dev runner's free-port search is skipped as well.- An inherited
T3CODE_HOST=0.0.0.0passes the proxiable-host check indevanddev:weband is forwarded to the dev backend. An inheritedT3CODE_LAN=truereaches the dev server through the spread env. Either way the dev backend binds every interface.
Agents had to unset the variables by hand before starting a dev server.
Root cause. The --port and --host flags fall back to the server's own variable names:
- https://github.com/pingdotgg/t3code/blob/43ce39595bf/scripts/dev-runner.ts#L958
Flag.withFallbackConfig(optionalStringConfig("T3CODE_HOST")) - https://github.com/pingdotgg/t3code/blob/43ce39595bf/scripts/dev-runner.ts#L963
Flag.withFallbackConfig(optionalPortConfig("T3CODE_PORT"))
The resulting port wins at L323 (const serverPort = port ?? BASE_SERVER_PORT + serverOffset). createDevRunnerEnv also spreads the inherited env, so an ambient T3CODE_HOST (L387 only writes it when a host was given) and T3CODE_LAN reach the spawned server. That server then reads them in apps/server/src/cli/config.ts (L432, privateNetworkOnly).
A T3 server's provider processes inherit its env. The integrated terminal already strips every T3CODE_* variable for this reason (https://github.com/pingdotgg/t3code/blob/43ce39595bf/apps/server/src/terminal/Manager.ts#L1358), but agent shells keep them. The dev runner can't tell an inherited T3CODE_PORT from one the developer set. T3CODE_HOME is already safe inside a worktree, because the worktree's .t3 outranks it.
Proposed fix (small, dev-runner only). Drop the env fallback for --port and --host, so only the explicit flags set them. T3CODE_PORT_OFFSET and T3CODE_DEV_INSTANCE stay as the env selectors, and no server sets them. Also delete an inherited T3CODE_HOST (when no --host is given) and T3CODE_LAN from the child env. The same approach already covers ambient VITE_DEV_SERVER_URL ("so a parent dev app cannot redirect the child runner"). The only behaviour change is that an undocumented T3CODE_PORT=x vp run dev is now ignored, and --port x does the same thing.
My fork carries this fix (Alb11747@4414c24) with a regression test in scripts/dev-runner.test.ts. The test runs the CLI with the parent server's env and asserts the spawned env. It fails on main (expected '3773' to equal '13773') and passes with the fix. I can't open a PR right now because I'm at the open-PR limit, but the change is about 20 lines if a maintainer wants to take it.
Impact
Minor bug or occasional failure
Version or commit
main @ 43ce395
Environment
Linux, Node 24.22.1; T3 Code background service on port 3773; reproduced from Claude agent shells.
Logs or stack traces
$ env | grep -E '^T3CODE_(PORT|HOST)='
T3CODE_HOST=0.0.0.0
T3CODE_PORT=3773
$ node scripts/dev-runner.ts dev:server --dry-run
[dev-runner] mode=dev:server source=worktree <worktree> serverPort=3773 webPort=8670 baseDir=<worktree>/.t3Workaround
env -u T3CODE_PORT -u T3CODE_HOST -u T3CODE_LAN vp run dev, or pass --port explicitly.
Activity
fix(dev): dev runner ignores the live server's port and network env