{"record":{"id":"d516edc9761fdf21","repo":"can1357/oh-my-pi","slug":"launch-program-resolves-to-a-directory-displayp","errorCode":null,"errorMessage":"launch program resolves to a directory: ${displayPath}. Pass an executable file path or choose an adapter that supports package directories.","messagePattern":"launch program resolves to a directory: (.+?)\\. Pass an executable file path or choose an adapter that supports package directories\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/debug.ts","lineNumber":548,"sourceCode":"\nasync function classifyLaunchProgram(program: string): Promise<LaunchProgramKind> {\n\ttry {\n\t\treturn (await fs.stat(program)).isDirectory() ? \"directory\" : \"file\";\n\t} catch (error) {\n\t\tif (isEnoent(error)) return \"missing\";\n\t\tthrow error;\n\t}\n}\n\nfunction validateLaunchProgram(\n\tprogram: string,\n\tcwd: string,\n\tprogramKind: LaunchProgramKind,\n\tadapter: DapResolvedAdapter,\n): void {\n\tif (programKind !== \"directory\" || adapter.acceptsDirectoryProgram) return;\n\tconst displayPath = formatPathRelativeToCwd(program, cwd, { trailingSlash: true });\n\tthrow new ToolError(\n\t\t`launch program resolves to a directory: ${displayPath}. Pass an executable file path or choose an adapter that supports package directories.`,\n\t);\n}\n\ninterface DebugRenderArgs extends Partial<DebugParams> {}\n\nfunction getActiveSessionSnapshot(): DapSessionSummary {\n\tconst snapshot = dapSessionManager.getActiveSession();\n\tif (!snapshot) {\n\t\tthrow new ToolError(\"No active debug session. Launch or attach first.\");\n\t}\n\treturn snapshot;\n}\n\nfunction requireCapability(capability: keyof DapCapabilities, description: string): DapSessionSummary {\n\tconst snapshot = getActiveSessionSnapshot();\n\tif (dapSessionManager.getCapabilities()?.[capability] !== true) {\n\t\tthrow new ToolError(`Current adapter does not support ${description}`);","sourceCodeStart":530,"sourceCodeEnd":566,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/debug.ts#L530-L566","documentation":"The debug tool refuses to launch when the `program` path passed to `action: \"launch\"` resolves to a directory and the selected DAP adapter does not accept directory programs (`adapter.acceptsDirectoryProgram` is false). validateLaunchProgram throws this after adapter selection, since most adapters expect an executable file entry point. The path is shown with a trailing slash to make the directory nature obvious.","triggerScenarios":"Calling the debug tool with action=launch and program set to a directory path (e.g. a package folder like `./myproject` or `~/src/app/`) when the chosen or auto-selected adapter requires a file program.","commonSituations":"Passing a Python package directory instead of `__main__.py` or the entry script; passing a project root to debugpy; passing a Go module directory instead of the built binary or main package; misconfigured launch configs that point at folders.","solutions":["Pass the executable file path instead of the directory (e.g. the entry script or compiled binary).","Select an adapter that supports package directories (one with acceptsDirectoryProgram) via the `adapter` parameter.","If launching a package, append the module entry point, e.g. point program at `pkg/__main__.py` or build first and launch the binary."],"exampleFix":"// before\n{ \"action\": \"launch\", \"program\": \"./my-python-package\" }\n// after\n{ \"action\": \"launch\", \"program\": \"./my-python-package/__main__.py\" }","handlingStrategy":"validation","validationCode":"import * as fs from \"node:fs\";\nconst st = fs.statSync(programPath);\nif (st.isDirectory()) {\n  // pick a directory-capable adapter or resolve to an entry file first\n}\nif (!st.isFile()) throw new Error(\"program must be an executable file\");","typeGuard":"function isFilePath(p: string): boolean {\n  try { return fs.statSync(p).isFile(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await debugTool({ action: \"launch\", program: p });\n} catch (e) {\n  if (String(e).includes(\"resolves to a directory\")) {\n    await debugTool({ action: \"launch\", program: path.join(p, \"__main__.py\") });\n  }\n}","preventionTips":["Stat the program path and assert isFile() before launching.","Point program at a concrete entry script or built binary, never a package root.","Check the adapter's acceptsDirectoryProgram capability when directories are unavoidable."],"tags":["debug","dap","validation","argument-error"],"backgroundTag":"program-path-is-directory","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}