{"record":{"id":"c80bc86103695c7c","repo":"Hmbown/CodeWhale","slug":"clipboard-action-write-requires-text","errorCode":null,"errorMessage":"clipboard action \"write\" requires text","messagePattern":"clipboard action \"write\" requires text","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/plugins/computer-use/src/tools.mjs","lineNumber":786,"sourceCode":"        : button === \"middle\" && clicks === 1 ? \"middle_click\"\n        : null;\n      if (!wire) throw bad(`click supports left with 1-3 clicks, right x1 or middle x1 (got ${JSON.stringify(button)} x${clicks})`);\n      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: {} };","sourceCodeStart":768,"sourceCodeEnd":804,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/plugins/computer-use/src/tools.mjs#L768-L804","documentation":"resolveTool's clipboard case: action 'write' was given without a string text argument; the write cannot proceed without content, so the tool call is rejected with a bad_args-shaped error before any backend dispatch.","triggerScenarios":"resolveTool(\"clipboard\", { action: \"write\" }) with no text, text: undefined, text: 123, or a non-string object.","commonSituations":"A model omits the text field for a clipboard write; a caller passes the content under a different key like \"value\" or \"content\"; text is a number the caller forgot to stringify.","solutions":["Add a string `text` field to the arguments","If the content is under another key, rename it to `text`","Stringify non-string payloads before passing them"],"exampleFix":"// before\nresolveTool(\"clipboard\", { action: \"write\", content: \"hello\" })\n// after\nresolveTool(\"clipboard\", { action: \"write\", text: \"hello\" })","handlingStrategy":"validation","validationCode":"if (args.action === 'write' && typeof args.text !== 'string') throw new Error('clipboard write needs string text');","typeGuard":"function isWritableClipboardArgs(a) { return typeof a.text === 'string'; }","tryCatchPattern":null,"preventionTips":["Always pass the payload under the key `text`","Stringify non-string content before writing","Validate arguments against the tool schema before resolveTool"],"tags":["validation","required-field","clipboard"],"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"}