Skip to content

V8 Inspector is not available in --require in node --test #48467

Open

Description

@connor4312

Version

v20.3.0

Platform

Darwin MacBook-Pro-2.local 22.5.0 Darwin Kernel Version 22.5.0: Mon Apr 24 20:51:50 PDT 2023; root:xnu-8796.121.2~5/RELEASE_X86_64 x86_64

Subsystem

test_runner

What steps will reproduce the bug?

  1. Have a file start-inspect.js containing:
const inspector = require("node:inspector");
inspector.open();
  1. Have some other file.test.js, which can be empty.
  2. Run NODE_OPTIONS="--require ./start-inspect.js" node --test ./hello.test.js

How often does it reproduce? Is there a required condition?

100%

What is the expected behavior? Why is that the expected behavior?

The inspector should open as usual, as if --test was not given in the CLI

What do you see instead?

$ NODE_OPTIONS="--require ./start-inspect.js" node --test ./hello.test.js

node:inspector:181
  open(port, host);
  ^
This Environment was initialized without a V8::Inspector
(Use `node --trace-uncaught ...` to show where the exception was thrown)

Node.js v20.3.0

Additional information

This does not happen if --test is omitted from the command. This causes issues with the VS/Code debugger which uses this mechanism to initiate debugging. I think Jetbrains does the same thing, so Webstorm and friends probably have the same issue, though I have not tested it.

Also, if I try to open the inspector in the test file itself, it works fine, so it seems like there might be some initialization ordering that's different for --test.

Originally reported on microsoft/vscode-js-debug#1727

Activity

  1. added
    inspectorIssues and PRs related to the V8 inspector protocol.
    test_runnerIssues and PRs related to the test runner subsystem.
    on Jun 15, 2023
  2. MoLow commented on Jun 25, 2023

    @MoLow
    Member

    I think this is because the code is trying to access the inspector both in the parent (orchestrator) process, and in the child process.
    I guess we should provide a way to determine whether you are inside a test file or not. @cjihrig WDYT?

    Edit:
    On second thought, This is expected to fail on the parent process, and can be handled with a simple try/catch.
    if you really need to know you are now in the main process you can look at the NODE_TEST_CONTEXT environment variable

    please LMK if this helps you.

  3. cjihrig commented on Jun 25, 2023

    @cjihrig
    Contributor

    I think we may want to look into skipping preloads in the test runner main process, but still propagating the preload flags to the child processes. I can't think of a good reason why preloads need to run for the main process.

  4. rluvaton commented on Jul 20, 2023

    @rluvaton
    Member

    Tested and had the same problem in webstorm as well

  5. damianobarbati commented on Feb 19, 2024

    @damianobarbati

    Any news on this? I also have the debugger broken in webstorm when using tsx :(

  6. github-actions commented on May 31, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  7. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on May 31, 2026
  8. connor4312 commented on Jun 1, 2026

    @connor4312
    ContributorAuthor

    Not stale

  9. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jun 2, 2026
  10. github-actions commented on Sep 1, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 90 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  11. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Sep 1, 2026
  12. connor4312 commented on Sep 1, 2026

    @connor4312
    ContributorAuthor

    Not stale

  13. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Sep 2, 2026
  14. SahinurDEV commented on Oct 12, 2026

    @SahinurDEV

    I'd like to pick this up, but since #52099 was blocked (semver-major, and it breaks --require-based TypeScript reporters/hooks in the orchestrator, per @GeoffreyBooth's review), I want to agree on an approach before opening a PR.

    Root cause. The error doesn't come from preloading itself. Since #44520 (--inspect support for --test), the orchestrator process never creates a V8 inspector, so --inspect* flags only take effect in the child test processes. That is the !(options_->test_runner && options_->test_isolation == "process") term in Environment::should_create_inspector() (src/env-inl.h), and --watch has the same term. --require modules still run in the orchestrator, which is intentional because it's how people register hooks and TS reporters. When one of them calls inspector.open(), which is what the VS Code and JetBrains bootloaders do, Agent::Start() was never called for this environment and the call throws ERR_INSPECTOR_NOT_AVAILABLE ("This Environment was initialized without a V8::Inspector").

    Proposal: create the inspector in the orchestrator, but don't activate it from CLI flags.

    • Remove the test_runner/watch_mode terms from should_create_inspector(), so the orchestrator gets an inspector client the way any plain node process does.
    • In Environment::InitializeInspector(), when the process is the test orchestrator (or the watch-mode parent), start the agent with a copy of debug_options() that has inspector_enabled, break_first_line, break_node_first_line and inspect_wait cleared. --inspect, --inspect-brk and --inspect-wait keep their current meaning: they are forwarded to the child processes (inspectPort, concurrency 1, etc.), and the parent neither listens nor pauses.
    • Leave profiler::StartProfilers() (NODE_V8_COVERAGE, --cpu-prof, --heap-prof) and the SIGUSR1 handler disabled in the orchestrator, as they are today. That way coverage tools and the child inspect ports see no change.

    After this, inspector.open() from a preload in the orchestrator behaves as it does in a non-inspected node process: it opens a session the IDE can attach to. Child processes are unchanged. Nothing that works today stops working: no preload is skipped, and the flags behave the same. The only observable difference is that a call that used to throw now succeeds, so I think this is semver-minor rather than major.

    Questions before I write it:

    1. Is it OK for the orchestrator to become debuggable through an explicit inspector.open()? IDE bootloaders would then attach to the orchestrator as well. connor4312 can probably say whether js-debug handles that well; it seems to already treat every process as a target.
    2. Should --watch get the same treatment? The cause is identical. I'd rather do both in one PR for consistency.
    3. Would you prefer a smaller alternative: keep things as they are, but give the orchestrator a clearer error and document NODE_TEST_CONTEXT as the way for bootloaders to detect it? That fixes nothing for IDEs, so I'd lean towards the proposal above.

    I have a prototype of this on a branch: https://github.com/SahinurDEV/node/tree/inspector-test-orchestrator (about 30 lines in src/env-inl.h, src/node.cc and src/inspector_profiler.cc, plus a regression test). If this direction sounds right, I'll open a PR with tests in test/parallel covering --require + inspector.open() with --test (and --watch), --inspect-brk + --test still pausing only in the children, and NODE_V8_COVERAGE output unchanged for the orchestrator.

    AI-assistance disclosure: I used an AI coding assistant to help investigate this and draft this comment. I have reviewed the analysis myself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    inspectorIssues and PRs related to the V8 inspector protocol.test_runnerIssues and PRs related to the test runner subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions