{"record":{"id":"8dc096207774da3a","repo":"Hmbown/CodeWhale","slug":"computer-action-must-be-list-switch-register-spawn-or-remove","errorCode":null,"errorMessage":"computer action must be list, switch, register, spawn or remove (got ${JSON.stringify(args.action)})","messagePattern":"computer action must be list, switch, register, spawn or remove \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":803,"sourceCode":"      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      }\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    }","sourceCodeStart":785,"sourceCodeEnd":821,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L785-L821","documentation":"Argument-validation guard in resolveTool for the 'computer' action: args.action matched none of list/switch/register/spawn/remove in the action-to-wire-name map, so no backend command name could be resolved. The received value is shown in the message.","triggerScenarios":"resolveTool(\"computer\", { action: \"delete\" }) or { action: \"Connect\" } or {} with no action.","commonSituations":"A model invents \"connect\" or \"delete\" (should be switch/remove); missing action field; wrong casing.","solutions":["Use one of: list, switch, register, spawn, remove","Lowercase the action value","Map \"connect\" to \"switch\" and \"delete\" to \"remove\" in the caller"],"exampleFix":"// before\nresolveTool(\"computer\", { action: \"connect\", id: \"vm1\" })\n// after\nresolveTool(\"computer\", { action: \"switch\", id: \"vm1\" })","handlingStrategy":"validation","validationCode":"if (!['list','switch','register','spawn','remove'].includes(args.action)) throw new Error('computer action must be list/switch/register/spawn/remove');","typeGuard":"function isComputerAction(a) { return ['list','switch','register','spawn','remove'].includes(a); }","tryCatchPattern":"try { resolveTool('computer', args); } catch (e) { if (String(e.message).includes('computer action')) { /* map synonyms connect->switch, delete->remove and retry */ } else throw e; }","preventionTips":["Map common synonyms (connect/delete) to supported actions before calling","Normalize action casing","Consult the tool schema's action enum"],"tags":["validation","enum","computer"],"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-22T11:17:16.035Z"}