dotnet/runtime · error · Error

Failed on mono_wasm_send_dbg_command

Error message

Failed on mono_wasm_send_dbg_command

What it means

Thrown by `mono_wasm_send_dbg_command` when the queued response for `id` carries `res_ok === false`. Same contract as the with-parms variant, but for commands that take only a parameter buffer. The native debugger reported failure for the command identified by `(command_set, command)`.

Solutions

  1. Validate the `command_set`/`command` pair against the runtime's supported debugger commands for the loaded build.
  2. Ensure the debugger is still attached (`mono_wasm_debugger_attached` was called) before issuing the command.
  3. Rebuild the BrowserDebugProxy and runtime together so the protocol versions align.
  4. Log `id` plus `(command_set, command)` to correlate with the native-side rejection.

Example fix

// before: command issued after detach
mono_wasm_detach_debugger();
mono_wasm_send_dbg_command(id, set, cmd, params); // throws

// after: keep the debugger attached for the duration of the command
mono_wasm_send_dbg_command(id, set, cmd, params);
mono_wasm_detach_debugger();
Defensive patterns

Strategy: try-catch

Validate before calling

function isSupportedCommandPair (command_set, command, supported) {
  return supported.has(`${command_set}:${command}`);
}

Type guard

function debuggerStillAttached (): boolean {
  return runtimeHelpers.waitForDebugger !== 0;
}

Try / catch

try {
  return mono_wasm_send_dbg_command(id, set, cmd, params);
} catch (e) {
  if (e instanceof Error && /Failed on mono_wasm_send_dbg_command/.test(e.message)) {
    mono_log_warn(`dbg command (${set},${cmd}) failed for id=${id}; re-attach and retry`);
    mono_wasm_debugger_attached();
    return mono_wasm_send_dbg_command(id, set, cmd, params);
  }
  throw e;
}

Prevention

When it happens

Trigger: A call to `mono_wasm_send_dbg_command(id, command_set, command, command_parameters)` (debug.ts:91) where the native side records a failing response. Typically caused by an unknown/unsupported `(command_set, command)` pair, an already-completed session, or malformed parameters.

Common situations: BrowserDebugProxy built against a different runtime debugger protocol; calling the function after `mono_wasm_detach_debugger`; sending a command that requires an active breakpoint context which no longer exists.

Related errors


AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10). Data as JSON: /api/errors/bfd9d5494d942b26. Report an issue: GitHub.

Appendix: source

Thrown at src/mono/browser/runtime/debug.ts:100

    mono_wasm_malloc_and_set_debug_buffer(command_parameters);
    cwraps.mono_wasm_send_dbg_command_with_parms(id, command_set, command, _debugger_buffer, length, valtype, newvalue.toString());

    const { res_ok, res } = commands_received.remove(id);
    if (!res_ok)
        throw new Error("Failed on mono_wasm_send_dbg_command_with_parms");
    return res;
}

export function mono_wasm_send_dbg_command (id: number, command_set: number, command: number, command_parameters: string): CommandResponseResult {
    forceThreadMemoryViewRefresh();

    mono_wasm_malloc_and_set_debug_buffer(command_parameters);
    cwraps.mono_wasm_send_dbg_command(id, command_set, command, _debugger_buffer, command_parameters.length);

    const { res_ok, res } = commands_received.remove(id);

    if (!res_ok)
        throw new Error("Failed on mono_wasm_send_dbg_command");
    return res;

}

export function mono_wasm_get_dbg_command_info (): CommandResponseResult {
    const { res_ok, res } = commands_received.remove(0);

    if (!res_ok)
        throw new Error("Failed on mono_wasm_get_dbg_command_info");
    return res;
}

export function mono_wasm_debugger_resume (): void {
    forceThreadMemoryViewRefresh();
}

export function mono_wasm_detach_debugger (): void {
    forceThreadMemoryViewRefresh();

View on GitHub (pinned to 60108ba66e)