{"record":{"id":"ec9b18ceff90d78e","repo":"can1357/oh-my-pi","slug":"runinterminal-request-did-not-include-a-command","errorCode":null,"errorMessage":"runInTerminal request did not include a command","messagePattern":"runInTerminal request did not include a command","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/dap/session.ts","lineNumber":1372,"sourceCode":"\t\t\tbreakpointMutationQueue: Promise.resolve(),\n\t\t\toutputChunks: [],\n\t\t\toutputBytes: 0,\n\t\t\toutputBufferedBytes: 0,\n\t\t\toutputTruncated: false,\n\t\t\tstop: {},\n\t\t\tthreads: [],\n\t\t\tlastStackFrames: [],\n\t\t\tinitializedSeen: false,\n\t\t\tneedsConfigurationDone: false,\n\t\t\tconfigurationDoneSent: false,\n\t\t\tparentSessionId,\n\t\t\tchildSessionIds: new Set(),\n\t\t\tport: client.port,\n\t\t};\n\t\tclient.onReverseRequest(\"runInTerminal\", async rawArgs => {\n\t\t\tconst args = (rawArgs ?? {}) as DapRunInTerminalArguments;\n\t\t\tif (!Array.isArray(args.args) || args.args.length === 0) {\n\t\t\t\tthrow new Error(\"runInTerminal request did not include a command\");\n\t\t\t}\n\t\t\tconst env = Object.fromEntries(\n\t\t\t\tObject.entries(args.env ?? {}).filter((entry): entry is [string, string] => entry[1] !== null),\n\t\t\t);\n\t\t\tconst proc = ptree.spawn(args.args, {\n\t\t\t\tcwd: path.resolve(session.cwd, args.cwd ?? \".\"),\n\t\t\t\tstdin: \"pipe\",\n\t\t\t\tenv: {\n\t\t\t\t\t...Bun.env,\n\t\t\t\t\t...NON_INTERACTIVE_ENV,\n\t\t\t\t\t...env,\n\t\t\t\t},\n\t\t\t\tdetached: true,\n\t\t\t});\n\t\t\t// Consume the child's stdout — ptree pipes it but drains only stderr,\n\t\t\t// so an unconsumed stream buffers unboundedly in this process.\n\t\t\tvoid drainTerminalStdout(proc.stdout, session);\n\t\t\treturn { processId: proc.pid } satisfies DapRunInTerminalResponse;","sourceCodeStart":1354,"sourceCodeEnd":1390,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/dap/session.ts#L1354-L1390","documentation":"When the adapter sends a runInTerminal reverse request, it must supply the command to execute in args.args. The handler spawns that command in the session's terminal; if the args array is missing or empty there is nothing to spawn, so it throws back to the adapter rather than attempting an undefined execution.","triggerScenarios":"Adapter sends runInTerminal reverse request with args undefined, or args.args missing/not an array, or an empty array; malformed/misbehaving adapter that does not follow the DAP runInTerminal schema; custom adapter implementations that pass console/command in the wrong field.","commonSituations":"Third-party or older adapter versions that don't populate runInTerminal args correctly; adapter configured for 'integratedTerminal' console but sends an empty command; custom debug adapters built against a different DAP version.","solutions":["Update or fix the debug adapter so it sends a proper runInTerminal request with args array (argv form)","Check adapter version compatibility with the DAP spec and switch to a supported adapter version","If using a custom adapter, populate args (e.g. ['node', 'program.js']) and include cwd/env as needed","Avoid adapter configurations that require runInTerminal (use internalConsole) if the adapter cannot supply commands"],"exampleFix":"// adapter side, before\nsend({ command: 'runInTerminal', arguments: { kind: 'integrated', title: 'debug' } });\n// after\nsend({ command: 'runInTerminal', arguments: { kind: 'integrated', title: 'debug', args: ['node', 'app.js'], cwd: '...', env: {} } });","handlingStrategy":"try-catch","validationCode":"if (!Array.isArray(rtArgs.args) || rtArgs.args.length === 0) {\n  console.error('adapter sent runInTerminal without a command; adapter version unsupported');\n}","typeGuard":"function hasRunInTerminalCommand(args: unknown): args is { args: string[]; cwd?: string; env?: Record<string, string | null> } {\n  return typeof args === 'object' && args !== null && Array.isArray((args as { args?: unknown }).args) && (args as { args: unknown[] }).args.length > 0;\n}","tryCatchPattern":"client.onReverseRequest('runInTerminal', async rawArgs => {\n  try {\n    await spawnInTerminal(rawArgs);\n  } catch (err) {\n    if (String((err as Error).message).includes('did not include a command')) {\n      return { processId: undefined }; // report failure back to the adapter gracefully\n    }\n    throw err;\n  }\n});","preventionTips":["Pin adapters to versions known to emit spec-compliant runInTerminal requests","Prefer internalConsole adapter configs when terminal spawning is not required","Validate reverse-request args against the DAP schema before acting on them","If using a custom adapter, test its runInTerminal payload shape end-to-end"],"tags":["dap","protocol","reverse-request","validation"],"backgroundTag":"malformed-dap-reverse-request","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}