{"record":{"id":"3a096379a21ee592","repo":"Hmbown/CodeWhale","slug":"computer-action-args-action-requires-id","errorCode":null,"errorMessage":"computer action \"${args.action}\" requires id","messagePattern":"computer action \"(.+?)\" requires id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":805,"sourceCode":"        return { name: \"write_clipboard\", args: { text: rest.text, computer: rest.computer } };\n      }\n      throw bad(`clipboard action must be \"read\" or \"write\" (got ${JSON.stringify(args.action)})`);\n    }\n    case \"recording\": {\n      const rest = { ...args };\n      delete rest.action;\n      const wire = { start: \"recording_start\", stop: \"recording_stop\", status: \"recording_status\", list: \"recording_list\" }[args.action];\n      if (!wire) throw bad(`recording action must be start, stop, status or list (got ${JSON.stringify(args.action)})`);\n      if ((args.action === \"stop\" || args.action === \"status\") && rest.id == null) throw bad(`recording action \"${args.action}\" requires id`);\n      return { name: wire, args: rest };\n    }\n    case \"computer\": {\n      const rest = { ...args };\n      delete rest.action;\n      const wire = { list: \"computer_list\", switch: \"computer_switch\", register: \"computer_register\", spawn: \"computer_spawn\", remove: \"computer_remove\" }[args.action];\n      if (!wire) throw bad(`computer action must be list, switch, register, spawn or remove (got ${JSON.stringify(args.action)})`);\n      if (args.action === \"list\") return { name: wire, args: {} };\n      if (rest.id == null) throw bad(`computer action \"${args.action}\" requires id`);\n      const id = rest.id;\n      delete rest.id;\n      return { name: wire, args: { ...rest, computer: id } };\n    }\n    case \"consent\": {\n      const rest = { ...args };\n      delete rest.action;\n      const wire = { status: \"consent_status\", allow: \"consent_allow\", deny: \"consent_deny\", revoke: \"consent_revoke\" }[args.action];\n      if (!wire) throw bad(`consent action must be status, allow, deny or revoke (got ${JSON.stringify(args.action)})`);\n      if (args.action === \"status\") return { name: wire, args: { computer: rest.computer } };\n      const foreground = rest.scope === \"foreground\";\n      if (!foreground && rest.app == null && rest.name == null && rest.bundle_id == null && rest.pid == null) {\n        throw bad(`consent action \"${args.action}\" needs an app (name, bundle_id, pid or app string) — or scope:\"foreground\" for the shared-pointer decision`);\n      }\n      return { name: wire, args: rest };\n    }\n    case \"key\": {\n      if (args.duration == null) return { name, args };","sourceCodeStart":787,"sourceCodeEnd":823,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L787-L823","documentation":"Argument-validation guard in resolveTool for 'computer': the action requires addressing an existing computer (switch/remove etc.), but the id field is missing from the args. The request never reaches the wire layer.","triggerScenarios":"resolveTool(\"computer\", { action: \"remove\" }) without id; id:null; intending \"list\" but passing \"switch\".","commonSituations":"A caller removes or switches to a computer without knowing its id; the model omits the id; action typo making list become another action.","solutions":["Pass the target computer's id","Call action \"list\" first to enumerate computer ids","Verify the action is actually \"list\" if you intended an id-less call"],"exampleFix":"// before\nresolveTool(\"computer\", { action: \"switch\" })\n// after\nresolveTool(\"computer\", { action: \"switch\", id: \"vm-7\" })","handlingStrategy":"validation","validationCode":"if (args.action !== 'list' && args.id == null) throw new Error(`computer ${args.action} requires id`);","typeGuard":"function computerIdProvided(a) { return a.action === 'list' || (a.id !== undefined && a.id !== null); }","tryCatchPattern":"try { resolveTool('computer', args); } catch (e) { if (String(e.message).includes('requires id')) { /* call computer list, pick id, retry */ } else throw e; }","preventionTips":["Resolve computer ids via the list action before acting","Only list is id-less; require id for all other actions","Pass id under the exact key `id`"],"tags":["validation","required-field","computer"],"backgroundTag":"missing-required-argument","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T16:17:23.217Z"}