Hmbown/CodeWhale · error
computer action " " requires id
Error message
computer action "${args.action}" requires id What it means
Argument-validation guard in resolveTool for 'computer': the action requires addressing an existing computer (switch/remove etc.), but the id field is missing from the args. The request never reaches the wire layer.
Solutions
- Pass the target computer's id
- Call action "list" first to enumerate computer ids
- Verify the action is actually "list" if you intended an id-less call
Example fix
// before
resolveTool("computer", { action: "switch" })
// after
resolveTool("computer", { action: "switch", id: "vm-7" }) Defensive patterns
Strategy: validation
Validate before calling
if (args.action !== 'list' && args.id == null) throw new Error(`computer ${args.action} requires id`); Type guard
function computerIdProvided(a) { return a.action === 'list' || (a.id !== undefined && a.id !== null); } Try / catch
try { resolveTool('computer', args); } catch (e) { if (String(e.message).includes('requires id')) { /* call computer list, pick id, retry */ } else throw e; } Prevention
- Resolve computer ids via the list action before acting
- Only list is id-less; require id for all other actions
- Pass id under the exact key `id`
When it happens
Trigger: resolveTool("computer", { action: "remove" }) without id; id:null; intending "list" but passing "switch".
Common situations: A caller removes or switches to a computer without knowing its id; the model omits the id; action typo making list become another action.
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 "write" requires text
- computer action must be list, switch, register, spawn or…
- 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/3a096379a21ee592.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/plugins/computer-use/src/tools.mjs:805
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;
return { name: wire, args: { ...rest, computer: id } };
}
case "consent": {
const rest = { ...args };
delete rest.action;
const wire = { status: "consent_status", allow: "consent_allow", deny: "consent_deny", revoke: "consent_revoke" }[args.action];
if (!wire) throw bad(`consent action must be status, allow, deny or revoke (got ${JSON.stringify(args.action)})`);
if (args.action === "status") return { name: wire, args: { computer: rest.computer } };
const foreground = rest.scope === "foreground";
if (!foreground && rest.app == null && rest.name == null && rest.bundle_id == null && rest.pid == null) {
throw bad(`consent action "${args.action}" needs an app (name, bundle_id, pid or app string) — or scope:"foreground" for the shared-pointer decision`);
}
return { name: wire, args: rest };
}
case "key": {
if (args.duration == null) return { name, args };View on GitHub (pinned to 73e0f67d83)