{"record":{"id":"ae13a93e35d40d58","repo":"Hmbown/CodeWhale","slug":"click-supports-left-with-1-3-clicks-right-x1-or-middle-x1","errorCode":null,"errorMessage":"click supports left with 1-3 clicks, right x1 or middle x1 (got ${JSON.stringify(button)} x${clicks})","messagePattern":"click supports left with 1-3 clicks, right x1 or middle x1 \\(got (.+?) x(.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":770,"sourceCode":" * fails as bad_args with the requested name. Unknown names pass through\n * unchanged — the alias surface is the rest of TOOLS.\n */\nexport function resolveTool(name, args = {}) {\n  const bad = (message) => Object.assign(new Error(message), { code: \"bad_args\" });\n  switch (name) {\n    case \"click\": {\n      const button = args.button ?? \"left\";\n      const clicks = args.clicks ?? 1;\n      const rest = { ...args };\n      delete rest.button;\n      delete rest.clicks;\n      const wire = button === \"left\" && clicks === 1 ? \"left_click\"\n        : button === \"left\" && clicks === 2 ? \"double_click\"\n        : button === \"left\" && clicks === 3 ? \"triple_click\"\n        : button === \"right\" && clicks === 1 ? \"right_click\"\n        : button === \"middle\" && clicks === 1 ? \"middle_click\"\n        : null;\n      if (!wire) throw bad(`click supports left with 1-3 clicks, right x1 or middle x1 (got ${JSON.stringify(button)} x${clicks})`);\n      if (button !== \"left\") delete rest.strategy; // strategy is an a11y-left-click concept\n      return { name: wire, args: rest };\n    }\n    case \"pointer\": {\n      const rest = { ...args };\n      delete rest.action;\n      const wire = { move: \"mouse_move\", down: \"left_mouse_down\", up: \"left_mouse_up\" }[args.action];\n      if (!wire) throw bad(`pointer action must be \"move\", \"down\" or \"up\" (got ${JSON.stringify(args.action)})`);\n      return { name: wire, args: rest };\n    }\n    case \"clipboard\": {\n      const rest = { ...args };\n      delete rest.action;\n      if (args.action === \"read\") return { name: \"read_clipboard\", args: { computer: rest.computer } };\n      if (args.action === \"write\") {\n        if (typeof rest.text !== \"string\") throw bad(\"clipboard action \\\"write\\\" requires text\");\n        return { name: \"write_clipboard\", args: { text: rest.text, computer: rest.computer } };\n      }","sourceCodeStart":752,"sourceCodeEnd":788,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L752-L788","documentation":"The computer-use plugin's `click` tool resolver maps a high-level click spec (button + clicks) onto a wire protocol tool name. It only supports left with 1-3 clicks, right x1, or middle x1; any other combination is rejected with this error because no corresponding wire tool exists.","triggerScenarios":"Calling resolveTool for tool \"click\" with e.g. button:\"right\" and clicks:2, button:\"middle\" and clicks:2, button:\"triple\", or clicks:0/4 with any button — any combination not in the wire mapping table.","commonSituations":"An LLM or automation script emits double-right-click or quadruple-left-click; a UI wrapper passes a numeric button code instead of \"left\"/\"right\"/\"middle\"; a model hallucinates a button name like \"primary\".","solutions":["Use button \"left\" with clicks 1, 2, or 3, or \"right\"/\"middle\" with clicks 1","If a double-right-click is needed, issue two separate click calls with button:\"right\", clicks:1","Fix the caller to send the button as a lowercase string \"left\"|\"right\"|\"middle\", not a number or alias"],"exampleFix":"// before\nresolveTool(\"click\", { button: \"right\", clicks: 2 })\n// after\nresolveTool(\"click\", { button: \"right\", clicks: 1 }) // issued twice, or left/double-click if that was meant","handlingStrategy":"validation","validationCode":"const CLICKS = { left: [1,2,3], right: [1], middle: [1] };\nfunction validClick(args) { return CLICKS[args.button]?.includes(args.clicks) ?? false; }\nif (!validClick(args)) throw new Error(`bad click spec: ${JSON.stringify(args)}`);","typeGuard":"function isClickSpec(a) { return (a.button === 'left' && [1,2,3].includes(a.clicks)) || ((a.button === 'right' || a.button === 'middle') && a.clicks === 1); }","tryCatchPattern":null,"preventionTips":["Coerce/normalize button and clicks to canonical string/number types before calling","Keep a lookup table of valid button/clicks combinations in the caller","Split multi-click right/middle actions into repeated single-click calls"],"tags":["validation","arguments","computer-use"],"backgroundTag":"invalid-enum-value","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}