{"record":{"id":"4cb51fade656ee80","repo":"Hmbown/CodeWhale","slug":"recording-action-args-action-requires-id","errorCode":null,"errorMessage":"recording action \"${args.action}\" requires id","messagePattern":"recording action \"(.+?)\" requires id","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":796,"sourceCode":"      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];\n      if (!wire) throw bad(`consent action must be status, allow, deny or revoke (got ${JSON.stringify(args.action)})`);","sourceCodeStart":778,"sourceCodeEnd":814,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L778-L814","documentation":"Argument-validation guard in resolveTool for 'recording': the action resolved to stop or status, both of which address an existing recording, but rest.id is null/undefined. The request is rejected before the wire command is built.","triggerScenarios":"resolveTool(\"recording\", { action: \"stop\" }) or { action: \"status\" } without an id field; id explicitly set to null.","commonSituations":"A caller stops a recording without remembering the id returned by start; the model forgets the id parameter; a caller lists recordings but accidentally sends stop.","solutions":["Pass the id of the recording (obtained from recording start or the list action)","Call action \"list\" first to discover available recording ids","If you only wanted recording state without an id, use action \"list\""],"exampleFix":"// before\nresolveTool(\"recording\", { action: \"stop\" })\n// after\nresolveTool(\"recording\", { action: \"stop\", id: \"rec-42\" })","handlingStrategy":"validation","validationCode":"if ((args.action === 'stop' || args.action === 'status') && args.id == null) throw new Error(`${args.action} requires recording id`);","typeGuard":"function recordingIdProvided(a) { return a.id !== undefined && a.id !== null; }","tryCatchPattern":"try { resolveTool('recording', args); } catch (e) { if (String(e.message).includes('requires id')) { /* fetch id via list, then retry */ } else throw e; }","preventionTips":["Store the id returned by recording start","Call list first when the id is unknown","Only omit id for start and list actions"],"tags":["validation","required-field","recording"],"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"}