{"record":{"id":"fefafeb9464e8ee2","repo":"can1357/oh-my-pi","slug":"program-is-required-for-launch","errorCode":null,"errorMessage":"program is required for launch","messagePattern":"program is required for launch","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/debug.ts","lineNumber":740,"sourceCode":"\t\treturn session.settings.get(\"debug.enabled\") ? new DebugTool(session) : null;\n\t}\n\n\tasync execute(\n\t\t_toolCallId: string,\n\t\tparams: DebugParams,\n\t\tsignal?: AbortSignal,\n\t\t_onUpdate?: AgentToolUpdateCallback<DebugToolDetails>,\n\t\t_context?: AgentToolContext,\n\t): Promise<AgentToolResult<DebugToolDetails>> {\n\t\tconst timeoutSec = clampTimeout(\"debug\", params.timeout, this.session.settings.get(\"tools.maxTimeout\"));\n\t\tconst timeoutSignal = AbortSignal.timeout(timeoutSec * 1000);\n\t\tconst combinedSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;\n\t\tconst details: DebugToolDetails = { action: params.action, success: true };\n\t\tconst result = toolResult(details);\n\t\tswitch (params.action) {\n\t\t\tcase \"launch\": {\n\t\t\t\tif (!params.program) {\n\t\t\t\t\tthrow new ToolError(\"program is required for launch\");\n\t\t\t\t}\n\t\t\t\tconst commandCwd = params.cwd ? resolveToCwd(params.cwd, this.session.cwd) : this.session.cwd;\n\t\t\t\tconst program = resolveToCwd(params.program, commandCwd);\n\t\t\t\tconst programKind = await classifyLaunchProgram(program);\n\t\t\t\tconst selection = selectLaunchAdapter(program, commandCwd, params.adapter, programKind);\n\t\t\t\tif (selection.kind === \"unavailable\") {\n\t\t\t\t\tthrow new ToolError(formatAdapterUnavailable(selection.adapterName, selection.command, commandCwd));\n\t\t\t\t}\n\t\t\t\tif (selection.kind === \"none\") {\n\t\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\t`No debugger adapter available. Installed adapters: ${getConfiguredAdapters(commandCwd)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst { adapter } = selection;\n\t\t\t\tvalidateLaunchProgram(program, commandCwd, programKind, adapter);\n\t\t\t\tconst extraLaunchArguments = resolveLaunchOverrides(adapter, program, programKind);\n\t\t\t\tconst snapshot = await dapSessionManager.launch(\n\t\t\t\t\t{ adapter, program, args: params.args, cwd: commandCwd, extraLaunchArguments },","sourceCodeStart":722,"sourceCodeEnd":758,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/debug.ts#L722-L758","documentation":"The launch action requires a `program` parameter identifying what to debug. execute checks `!params.program` in the launch case and throws before any adapter resolution occurs. Without a program there is no target for the DAP adapter to launch.","triggerScenarios":"Calling the debug tool with action=\"launch\" but omitting the `program` parameter (or passing an empty string/undefined).","commonSituations":"Copy-pasting a tool invocation meant for attach (which uses pid/port) into launch; the orchestrating agent filled args for the wrong action; a config-driven invocation where the program field was dropped.","solutions":["Add the `program` parameter with the executable/entry-file path.","If you intended to debug an already-running process, use action=\"attach\" with `pid` or `port` instead.","If launching needs a working directory too, set `cwd` alongside `program`."],"exampleFix":"// before\n{ \"action\": \"launch\" }\n// after\n{ \"action\": \"launch\", \"program\": \"./src/main.py\", \"cwd\": \"./src\" }","handlingStrategy":"validation","validationCode":"function assertLaunchArgs(params: { action: string; program?: string }): asserts params is { action: \"launch\"; program: string } {\n  if (params.action === \"launch\" && !params.program) throw new Error(\"program required for launch\");\n}","typeGuard":"function hasProgram(p: { program?: string }): p is { program: string } & typeof p {\n  return typeof p.program === \"string\" && p.program.length > 0;\n}","tryCatchPattern":"try {\n  return await debugTool({ action: \"launch\", program });\n} catch (e) {\n  if (String(e).includes(\"program is required for launch\")) {\n    return await debugTool({ action: \"attach\", pid }); // attach semantics instead\n  }\n  throw e;\n}","preventionTips":["Validate tool-call params against the action's required fields before dispatching.","Use typed discriminated unions for launch vs attach argument shapes.","Default program from project entry-point conventions in your automation."],"tags":["debug","dap","validation","missing-argument"],"backgroundTag":"missing-required-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}