{"record":{"id":"9ea647a05a099d2e","repo":"Hmbown/CodeWhale","slug":"recording-action-must-be-start-stop-status-or-list-got-json","errorCode":null,"errorMessage":"recording action must be start, stop, status or list (got ${JSON.stringify(args.action)})","messagePattern":"recording action must be start, stop, status or list \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":795,"sourceCode":"      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      }\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];","sourceCodeStart":777,"sourceCodeEnd":813,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L777-L813","documentation":"Argument-validation guard in the computer-use plugin's resolveTool for the 'recording' action: args.action did not match any of start/stop/status/list in the action-to-wire-name map, so no backend command could be resolved. The offending value is echoed in the message.","triggerScenarios":"resolveTool(\"recording\", { action: \"pause\" }) or { action: \"Start\" } or {} with no action at all.","commonSituations":"A model tries a \"pause\"/\"resume\" action that does not exist; action field omitted; wrong casing like \"Stop\".","solutions":["Use one of the supported actions: start, stop, status, list","Fix casing to lowercase","Drop unsupported operations — there is no pause/resume; stop then start a new recording"],"exampleFix":"// before\nresolveTool(\"recording\", { action: \"pause\" })\n// after\nresolveTool(\"recording\", { action: \"stop\", id: \"rec1\" })","handlingStrategy":"validation","validationCode":"if (!['start','stop','status','list'].includes(args.action)) throw new Error('recording action must be start/stop/status/list');","typeGuard":"function isRecordingAction(a) { return ['start','stop','status','list'].includes(a); }","tryCatchPattern":"try { resolveTool('recording', args); } catch (e) { if (String(e.message).includes('recording action')) { /* correct the action and retry */ } else throw e; }","preventionTips":["Normalize action casing","Model pause/resume as stop + start, not new actions","Validate against the enum before dispatch"],"tags":["validation","enum","recording"],"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-23T08:17:48.524Z"}