{"record":{"id":"4871b3b710f2c5e9","repo":"Hmbown/CodeWhale","slug":"clipboard-action-must-be-read-or-write-got-json-stringify","errorCode":null,"errorMessage":"clipboard action must be \"read\" or \"write\" (got ${JSON.stringify(args.action)})","messagePattern":"clipboard action must be \"read\" or \"write\" \\(got (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":789,"sourceCode":"      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      }\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;","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L771-L807","documentation":"The `clipboard` tool accepts exactly two actions: \"read\" and \"write\". Anything else (or an absent action) falls through both checks and is rejected with this error, since no wire tool maps the given action.","triggerScenarios":"resolveTool(\"clipboard\", {}) with no action; action:\"clear\", \"paste\", \"Read\" (wrong case), or any unknown value.","commonSituations":"A model invents a clipboard action like \"clear\"; the action field is omitted; case sensitivity mistakes such as \"Write\".","solutions":["Set action to exactly \"read\" or \"write\"","Lowercase the action value before calling","For clearing, consider writing an empty string instead"],"exampleFix":"// before\nresolveTool(\"clipboard\", { action: \"Read\" })\n// after\nresolveTool(\"clipboard\", { action: \"read\" })","handlingStrategy":"validation","validationCode":"if (args.action !== 'read' && args.action !== 'write') throw new Error('clipboard action must be read or write');","typeGuard":"function isClipboardAction(a) { return a === 'read' || a === 'write'; }","tryCatchPattern":"try { resolveTool('clipboard', args); } catch (e) { if (String(e.message).includes('clipboard action')) { args.action = String(args.action || '').toLowerCase(); /* retry or report */ } else throw e; }","preventionTips":["Normalize the action to lowercase before calling","Check the tool's action enum in its schema","Avoid inventing actions like clear/paste"],"tags":["validation","enum","clipboard"],"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"}