Skip to content

fix(launch): strip ELECTRON_RUN_AS_NODE from the child env so TradingView starts as Electron - #519

Open
shshs21 wants to merge 1 commit into
tradesdontlie:mainfrom
shshs21:fix/electron-run-as-node
Open

shshs21 wants to merge 1 commit into
tradesdontlie:mainfrom
shshs21:fix/electron-run-as-node

Conversation

@shshs21

@shshs21 shshs21 commented Sep 12, 2026

Copy link
Copy Markdown

Problem

_spawnDetached passes no env, so the spawned TradingView process inherits the
server's entire environment — including ELECTRON_RUN_AS_NODE.

When an Electron application hosts the MCP server, that variable is set to 1.
The most common case is the VS Code extension host, which sets it for
extensions it launches; an MCP client running there (Claude Code, for example)
passes it to the server process, and the server passes it to TradingView.

With it set, the TradingView binary starts as a plain Node runtime rather than
Electron, and rejects Chromium's flag:

TradingView.exe: bad option: --remote-debugging-port=9222

The process then exits and CDP never binds.

That message is Node's CLI parser, not Chromium's

Worth stating explicitly, because the error reads like TradingView dropped support
for the flag. Running the same binary with --help shows what is actually
happening:

$ TradingView.exe --help
Usage: node [options] [ script.js ] [arguments]
       node inspect [options] [ script.js | host:port ] [arguments]

Options:
  -                           script read from stdin ...
  --abort-on-uncaught-exception
  --allow-addons              allow use of addons when any permissions are set
  ...

That is Node's usage text. The binary is Electron — resources/app.asar,
icudtl.dat, v8_context_snapshot.bin, and the Chromium .pak files are all
present next to it — it is simply being asked to behave as Node.

Reproduce

ELECTRON_RUN_AS_NODE=1 node src/cli/index.js launch --port 9222

Or call tv_launch from any MCP client hosted inside VS Code.

Secondary cost: the MSIX fallback fires for the wrong reason

launch treats any early exit as a failed direct spawn, so this bug falls through
to _copyMsixPackageLocal and copies ~382 MB into %LOCALAPPDATA%\tradingview-mcp\.
The copy then fails identically, because the environment variable is still
inherited. The user pays a large one-time copy and gets pointed at a Store/MSIX
explanation that is not the cause.

With the variable stripped, TradingView launches directly from
C:\Program Files\WindowsApps\... and CDP binds normally. The fallback was never
needed on this machine.

It may be worth checking whether some existing "MSIX blocks the debug port"
reports are this same bug — the symptom is identical from the outside, and any
user running the server under VS Code would hit it regardless of how TradingView
was installed.

Changes

  1. _spawnDetached strips ELECTRON_RUN_AS_NODE from the child environment.

    const { ELECTRON_RUN_AS_NODE, ...env } = process.env;
    const child = spawnFn(exe, args, { detached: true, stdio: 'ignore', env });
  2. launch now returns success: false when CDP never bound. It previously
    returned success: true next to cdp_ready: false, so a caller checking only
    success saw a dead launch as a pass — which is what let this fail quietly.
    tests/launch.test.js is updated to match.

Happy to drop change 2 into its own PR, or leave it out entirely, if you would
rather keep the return shape as-is.

Verification

  • Windows 11 26200, TradingView Desktop 3.4.1.8194 (MSIX), Node v20.17.0
  • Before: success: true, cdp_ready: false, 382 MB copied, CDP never binds
  • After, with ELECTRON_RUN_AS_NODE=1 still set: launches from WindowsApps,
    no fallback copy, tv_health_check returns cdp_connected: true
  • npm run test:unit — 125/125 pass
  • npm run lint — no new warnings

One pre-existing failure is unrelated and present on main before this change:
source audit — no unsafe interpolation patterns in tests/sanitization.test.js.
The e2e test tv_launch — auto-detect binary also fails on Windows independently
of this change, as it only probes macOS paths.

… mode

_spawnDetached passed no `env`, so the child inherited ELECTRON_RUN_AS_NODE
from the parent. When an Electron app hosts the MCP server — notably Claude
Code in the VS Code extension host — that variable is set to 1, and the
TradingView binary starts as a plain Node runtime instead of Electron. It
then rejects Chromium's --remote-debugging-port:

    TradingView.exe: bad option: --remote-debugging-port=9222

That message is Node's CLI parser. `TradingView.exe --help` confirms it,
printing "Usage: node [options] [ script.js ] [arguments]" rather than the
Chromium switch list.

Strip the variable from the child environment.

Also report a launch where CDP never bound as success: false. It previously
returned success: true alongside cdp_ready: false, so a caller checking only
`success` saw a dead launch as a pass — which is what let this fail silently.
Test updated to match.

Side effect worth noting: because the direct spawn "failed early", launch fell
through to the MSIX local-copy path and copied ~382MB to LOCALAPPDATA, which
then failed for the same reason. With the variable cleared, TradingView starts
straight from WindowsApps and CDP binds normally — the fallback was never
needed on this machine.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant