Repository navigation
Description
Five answers on a session with children still describe the launched process alone. #1149 fixed the two reported as #1128 and #1137 (the end summary after a child stopped; the unexplained childrenReleased); these are what it left, kept in one place so none is lost.
1. A launch answer says "has not reached 1 breakpoint(s) yet" while its own children shows the child paused there
Measured 2026-11-12 on Windows, branch of #1149, server mcp-debugger-stdio: Python, breakpoint on tests/fixtures/python/subprocess-tree/child.py:12 only, start_debugging on parent.py.
"state": "running", "pending": true,
"message": "… The program is running and has not reached 1 breakpoint(s) yet. Nothing was cancelled: what is armed stays armed, and the session will report 'paused' when the program gets there — call wait_for_stop …",
"children": [{ "sessionId": "…", "name": "Subprocess 37340", "state": "paused", … }]
The child reached the breakpoint inside the launch hold. The message is about the launched process, the children list is about the tree, and the two disagree in one answer. A following wait_for_stop does answer the child's stop, so nothing is lost; the sentence is what misleads.
2. "Never bound during this run … check the file path and line" for a breakpoint only a child could bind
Measured the same day: JavaScript, DEBUG_MCP_MAX_CHILD_SESSIONS=0, breakpoint on subprocess-tree/child.js:14, launch parent.js. The launch answer now explains the released child in its message, and beside it still carries:
"warning": "1 breakpoint(s) never bound during this run: child.js:14 (Unbound breakpoint). The program ran to completion without stopping there — check the file path and line, or list_breakpoints for the full per-breakpoint state"
The path is right; the file was never loaded in the launched process. buildUnboundBreakpointExitWarning (src/session/breakpoints/launch-warnings.ts) reads the root's records only. The same applies when a child was adopted and bound the breakpoint but the root ended inside the launch hold: the review of #1149 showed, on the mock adapter, an answer that says "Its child sessions stopped 1 time during this run" beside the same warning.
3. unhitBreakpoints[].verified is the launched process's flag
When children were adopted but none stopped, the root's end answer lists its breakpoints as unhit with the root's own verified. For JavaScript that is false for a breakpoint that bound in the child and simply was not reached. (When a child did stop, #1149 withholds the list.)
4. The subProcess: false opt-out still ends with "Verified but never hit: child.py:12"
From the comment on #1128: the run is correct (the child ran undebugged and the launch answer's warning says so), but calling a breakpoint that only an undebugged child can reach "verified" overstates it. The root has no record that a child existed, because with the opt-out nothing is reported. JavaScript's autoAttachChildProcesses: false is the same case.
5. A grandchild released under a child is not counted on the root's answers
childrenReleased counts releases on the answering session's own connection. With a cap of 1, a child adopted and a grandchild released under it, the root's pending answer still says "what is armed stays armed" with no childrenReleased and no sentence; the child's own answer has both. Shown on the mock adapter by the review of #1149; not run with a real adapter. A real grandchild is reported on its parent's connection (the Python and JavaScript tree fixtures have grandchild cases), so the same path is expected there. Counting on every ancestor (as #1149 does for a descendant's stops) would change what the field means, from "reported on this session's connection" to "in this session's tree". The session tree has not shipped in a release yet, so the meaning can still be chosen.
One fact would cover 2 and 4
"Children of this run are, or may be, running undebugged" is known in three ways: a released report (recorded since #1149 as releasedChildCauses), the launch opt-out (known to the adapter policy from the launch arguments), and an attach whose child debugging was turned off. With that as one per-run fact on the session, the end summary and the never-bound warning could both say "in the debugged process" and name why a child's breakpoint could not bind or hit. Items 1 and 3 need the tree's state, which the root can read from its descendants at answer time. Item 5 is a decision about the field's meaning.
Not known: whether any of the five has cost an agent a wrong turn in practice. Item 1 was seen on the first live run of the documented flow.
Activity