Hmbown/CodeWhale · error
clipboard action must be "read" or "write
Error message
clipboard action must be "read" or "write" (got ${JSON.stringify(args.action)}) What it means
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.
Solutions
- Set action to exactly "read" or "write"
- Lowercase the action value before calling
- For clearing, consider writing an empty string instead
Example fix
// before
resolveTool("clipboard", { action: "Read" })
// after
resolveTool("clipboard", { action: "read" }) Defensive patterns
Strategy: validation
Validate before calling
if (args.action !== 'read' && args.action !== 'write') throw new Error('clipboard action must be read or write'); Type guard
function isClipboardAction(a) { return a === 'read' || a === 'write'; } Try / catch
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; } Prevention
- Normalize the action to lowercase before calling
- Check the tool's action enum in its schema
- Avoid inventing actions like clear/paste
When it happens
Trigger: resolveTool("clipboard", {}) with no action; action:"clear", "paste", "Read" (wrong case), or any unknown value.
Common situations: A model invents a clipboard action like "clear"; the action field is omitted; case sensitivity mistakes such as "Write".
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- agent profile reasoning_effort must be one of: inherit…
- Choose approve or decline
- clipboard action "write" requires text
- computer action must be list, switch, register, spawn or…
- consent action must be status, allow, deny or revoke
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/4871b3b710f2c5e9.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/tools.mjs:789
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: {} };
if (rest.id == null) throw bad(`computer action "${args.action}" requires id`);
const id = rest.id;
delete rest.id;View on GitHub (pinned to 73e0f67d83)