Hmbown/CodeWhale · error
clipboard action "write" requires text
Error message
clipboard action "write" requires text
What it means
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.
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
Example fix
// before
resolveTool("clipboard", { action: "write", content: "hello" })
// after
resolveTool("clipboard", { action: "write", text: "hello" }) Defensive patterns
Strategy: validation
Validate before calling
if (args.action === 'write' && typeof args.text !== 'string') throw new Error('clipboard write needs string text'); Type guard
function isWritableClipboardArgs(a) { return typeof a.text === 'string'; } Prevention
- Always pass the payload under the key `text`
- Stringify non-string content before writing
- Validate arguments against the tool schema before resolveTool
When it happens
Trigger: resolveTool("clipboard", { action: "write" }) with no text, text: undefined, text: 123, or a non-string object.
Common situations: 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.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- clipboard action must be "read" or "write
- computer action " " requires id
- consent action " " needs an app (name, bundle_id, pid or…
- custom theme requires custom_theme_name
- recording action " " requires id
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/c80bc86103695c7c.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/tools.mjs:786
: button === "middle" && clicks === 1 ? "middle_click"
: null;
if (!wire) throw bad(`click supports left with 1-3 clicks, right x1 or middle x1 (got ${JSON.stringify(button)} x${clicks})`);
if (button !== "left") delete rest.strategy; // strategy is an a11y-left-click concept
return { name: wire, args: rest };
}
case "pointer": {
const rest = { ...args };
delete rest.action;
const wire = { move: "mouse_move", down: "left_mouse_down", up: "left_mouse_up" }[args.action];
if (!wire) throw bad(`pointer action must be "move", "down" or "up" (got ${JSON.stringify(args.action)})`);
return { name: wire, args: rest };
}
case "clipboard": {
const rest = { ...args };
delete rest.action;
if (args.action === "read") return { name: "read_clipboard", args: { computer: rest.computer } };
if (args.action === "write") {
if (typeof rest.text !== "string") throw bad("clipboard action \"write\" requires text");
return { name: "write_clipboard", args: { text: rest.text, computer: rest.computer } };
}
throw bad(`clipboard action must be "read" or "write" (got ${JSON.stringify(args.action)})`);
}
case "recording": {
const rest = { ...args };
delete rest.action;
const wire = { start: "recording_start", stop: "recording_stop", status: "recording_status", list: "recording_list" }[args.action];
if (!wire) throw bad(`recording action must be start, stop, status or list (got ${JSON.stringify(args.action)})`);
if ((args.action === "stop" || args.action === "status") && rest.id == null) throw bad(`recording action "${args.action}" requires id`);
return { name: wire, args: rest };
}
case "computer": {
const rest = { ...args };
delete rest.action;
const wire = { list: "computer_list", switch: "computer_switch", register: "computer_register", spawn: "computer_spawn", remove: "computer_remove" }[args.action];
if (!wire) throw bad(`computer action must be list, switch, register, spawn or remove (got ${JSON.stringify(args.action)})`);
if (args.action === "list") return { name: wire, args: {} };View on GitHub (pinned to 73e0f67d83)