Summary
Setting a logpoint on Ruby silently converts it into an ordinary pausing breakpoint, and every observable signal afterwards claims the logpoint is live and bound. A logpoint's entire contract is not halting the debuggee — so the agent asks for "log this at full speed" and instead gets a program frozen at a breakpoint, with nothing in the response telling it that happened.
set_breakpoint explicitly promises a later answer:
"warning": "Logpoint support for ruby is unknown; it will be validated against the adapter's capabilities at launch"
That answer never arrives. The launch response carries no downgrade warning, and list_breakpoints reports the logpoint as verified: true with its logMessage intact.
Reproduction (100% reproducible, v0.24.2)
Expected: either the program runs to completion emitting LOGPOINT value=1 …, or the response says plainly that ruby/rdbg cannot do logpoints and the request was downgraded/rejected.
Actual: the program is stopped, no log output exists, and the state an agent can observe asserts a verified logpoint.
Why this is worth fixing
This is the same inverted-signal family as #439 — the run that silently didn't work looks identical to the run that worked, in the one workflow where verified is the agent's only feedback. It is arguably worse than #439 because the downgrade also changes program behavior: an agent that sets a logpoint expects to keep running, so it will typically call get_output and wait, while the debuggee sits paused indefinitely.
The deferred-validation warning makes it more confusing, not less: it tells the caller a verdict is coming, and then no verdict is ever delivered on any channel.
Suggested fix
Any one of these closes the hole; the first two are complementary:
- Surface the resolved verdict at launch. When the adapter's capabilities are known (that is the moment the deferred warning refers to), put the downgrade in the
start_debugging response warning — "logpoint on fizzbuzz.rb:16 downgraded to a breakpoint; ruby/rdbg does not support logpoints".
- Stop reporting a downgraded logpoint as a verified logpoint.
list_breakpoints should either drop logMessage or add an explicit downgraded: true / message, so verified: true is not asserting something untrue.
- Optionally reject
logMessage for ruby up front rather than deferring, since the capability is knowable per-adapter.
Also worth checking whether the same silent path exists for java/.NET, which the set_breakpoint schema already documents as not supporting logMessage.
Found during a full /testdebugger sweep; reproduced independently on the local and npx groups, then confirmed by hand.
Summary
Setting a logpoint on Ruby silently converts it into an ordinary pausing breakpoint, and every observable signal afterwards claims the logpoint is live and bound. A logpoint's entire contract is not halting the debuggee — so the agent asks for "log this at full speed" and instead gets a program frozen at a breakpoint, with nothing in the response telling it that happened.
set_breakpointexplicitly promises a later answer:That answer never arrives. The launch response carries no downgrade warning, and
list_breakpointsreports the logpoint asverified: truewith itslogMessageintact.Reproduction (100% reproducible, v0.24.2)
create_debug_session { language: "ruby" } set_breakpoint { file: "examples/ruby/fizzbuzz.rb", line: 16, logMessage: "LOGPOINT value={value}" } → { success: true, verified: false, logMessage: "LOGPOINT value={value}", warning: "Logpoint support for ruby is unknown; it will be validated against the adapter's capabilities at launch" } start_debugging { scriptPath: "examples/ruby/fizzbuzz.rb", dapLaunchArgs: { stopOnEntry: false } } → { success: true, state: "paused", data: { reason: "breakpoint" } } // ← HALTED. No warning. get_output { } → only rdbg's REPL banner — no "LOGPOINT" text at all list_breakpoints { } → { logMessage: "LOGPOINT value={value}", verified: true } // ← claims it is liveExpected: either the program runs to completion emitting
LOGPOINT value=1 …, or the response says plainly that ruby/rdbg cannot do logpoints and the request was downgraded/rejected.Actual: the program is stopped, no log output exists, and the state an agent can observe asserts a verified logpoint.
Why this is worth fixing
This is the same inverted-signal family as #439 — the run that silently didn't work looks identical to the run that worked, in the one workflow where
verifiedis the agent's only feedback. It is arguably worse than #439 because the downgrade also changes program behavior: an agent that sets a logpoint expects to keep running, so it will typically callget_outputand wait, while the debuggee sits paused indefinitely.The deferred-validation warning makes it more confusing, not less: it tells the caller a verdict is coming, and then no verdict is ever delivered on any channel.
Suggested fix
Any one of these closes the hole; the first two are complementary:
start_debuggingresponsewarning— "logpoint on fizzbuzz.rb:16 downgraded to a breakpoint; ruby/rdbg does not support logpoints".list_breakpointsshould either droplogMessageor add an explicitdowngraded: true/ message, soverified: trueis not asserting something untrue.logMessagefor ruby up front rather than deferring, since the capability is knowable per-adapter.Also worth checking whether the same silent path exists for java/.NET, which the
set_breakpointschema already documents as not supportinglogMessage.Found during a full
/testdebuggersweep; reproduced independently on the local and npx groups, then confirmed by hand.