{"record":{"id":"02b7fdafc6d45d79","repo":"dotnet/runtime","slug":"failed-on-mono-wasm-send-dbg-command-with-parms","errorCode":null,"errorMessage":"Failed on mono_wasm_send_dbg_command_with_parms","messagePattern":"Failed on mono_wasm_send_dbg_command_with_parms","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/debug.ts","lineNumber":87,"sourceCode":"        _debugger_buffer_len = Math.max(command_parameters.length, _debugger_buffer_len, 256);\n        _debugger_buffer = malloc(_debugger_buffer_len);\n    }\n    const byteCharacters = atob(command_parameters);\n    const heapU8 = localHeapViewU8();\n    for (let i = 0; i < byteCharacters.length; i++) {\n        heapU8[<any>_debugger_buffer + i] = byteCharacters.charCodeAt(i);\n    }\n}\n\nexport function mono_wasm_send_dbg_command_with_parms (id: number, command_set: number, command: number, command_parameters: string, length: number, valtype: number, newvalue: number): CommandResponseResult {\n    forceThreadMemoryViewRefresh();\n\n    mono_wasm_malloc_and_set_debug_buffer(command_parameters);\n    cwraps.mono_wasm_send_dbg_command_with_parms(id, command_set, command, _debugger_buffer, length, valtype, newvalue.toString());\n\n    const { res_ok, res } = commands_received.remove(id);\n    if (!res_ok)\n        throw new Error(\"Failed on mono_wasm_send_dbg_command_with_parms\");\n    return res;\n}\n\nexport function mono_wasm_send_dbg_command (id: number, command_set: number, command: number, command_parameters: string): CommandResponseResult {\n    forceThreadMemoryViewRefresh();\n\n    mono_wasm_malloc_and_set_debug_buffer(command_parameters);\n    cwraps.mono_wasm_send_dbg_command(id, command_set, command, _debugger_buffer, command_parameters.length);\n\n    const { res_ok, res } = commands_received.remove(id);\n\n    if (!res_ok)\n        throw new Error(\"Failed on mono_wasm_send_dbg_command\");\n    return res;\n\n}\n\nexport function mono_wasm_get_dbg_command_info (): CommandResponseResult {","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/mono/browser/runtime/debug.ts#L69-L105","documentation":"Thrown by mono_wasm_send_dbg_command_with_parms() in debug.ts when the native Mono runtime reports a failed debugger command. This function is the JS half of the browser debugger proxy (CDP-style) used by the Chrome DevTools / VS Code .NET WASM debugger: it marshals a command with parameters (valtype/newvalue) into a heap buffer, invokes the native mono_wasm_send_dbg_command_with_parms cwrap, then reads the response that native pushed back via mono_wasm_add_dbg_command_received. When native sets res_ok=false it means the debugger engine rejected or failed the command.","triggerScenarios":"The debugger proxy calling a property setter/getter that references a stale get/set descriptor (see _create_proxy_from_object_id in debug.ts:201). A CDP `Runtime.callFunctionOn` against a dotnet: object whose native backing was collected or is on a paused runtime. The runtime being paused/transitioning (module load, GC) while a debugger property access is in flight. Native debugger engine hitting an internal error executing the command set/command id.","commonSituations":"Stepping/evaluating expressions during module load or while the runtime is mid-GC. Holding a stale object reference from an older evaluation after a restart/hot-reload. A version mismatch between the runtime wasm and the debug JS modules. Concurrent debugger operations racing on the shared _debugger_buffer.","solutions":["Retry the debugger operation after the runtime settles (it is often transient when fired during load/GC).","Restart the debug session / reload the page so the proxy and native object id cache are reset.","Ensure the runtime .wasm and all js-module-diagnostics/debug JS modules come from the same build (no partial cache).","If reproducing reliably, capture the command_set/command/id and report to the dotnet/runtime repo with a minimal repro; an internal native failure should not surface as a hard throw."],"exampleFix":"// The proxy getter in _create_proxy_from_object_id calls this; wrap callers:\n// before\nconst v = mono_wasm_send_dbg_command_with_parms(id, cs, cmd, buf, len, vt, newVal);\n\n// after\ntry {\n  const v = mono_wasm_send_dbg_command_with_parms(id, cs, cmd, buf, len, vt, newVal);\n} catch (e) {\n  // object may be stale or runtime paused; surface to user, do not crash\n  console.warn('debugger command failed', e);\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  const res = mono_wasm_send_dbg_command_with_parms(id, cs, cmd, buf, len, vt, val);\n  return res;\n} catch (e) {\n  // native rejected the command; object may be stale or runtime paused\n  console.warn('debugger command failed', { id, cs, cmd }, e);\n  return undefined;\n}","preventionTips":["Avoid issuing debugger commands while the runtime is mid-load or mid-GC.","Release stale object handles and re-acquire them after restarts.","Serve runtime wasm and debug JS from the same build."],"tags":["debugger","native-interop","cdp","devtools"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}