Hmbown/CodeWhale · error

recording action " " requires id

Error message

recording action "${args.action}" requires id

What it means

Argument-validation guard in resolveTool for 'recording': the action resolved to stop or status, both of which address an existing recording, but rest.id is null/undefined. The request is rejected before the wire command is built.

Solutions

  1. Pass the id of the recording (obtained from recording start or the list action)
  2. Call action "list" first to discover available recording ids
  3. If you only wanted recording state without an id, use action "list"

Example fix

// before
resolveTool("recording", { action: "stop" })
// after
resolveTool("recording", { action: "stop", id: "rec-42" })
Defensive patterns

Strategy: validation

Validate before calling

if ((args.action === 'stop' || args.action === 'status') && args.id == null) throw new Error(`${args.action} requires recording id`);

Type guard

function recordingIdProvided(a) { return a.id !== undefined && a.id !== null; }

Try / catch

try { resolveTool('recording', args); } catch (e) { if (String(e.message).includes('requires id')) { /* fetch id via list, then retry */ } else throw e; }

Prevention

When it happens

Trigger: resolveTool("recording", { action: "stop" }) or { action: "status" } without an id field; id explicitly set to null.

Common situations: A caller stops a recording without remembering the id returned by start; the model forgets the id parameter; a caller lists recordings but accidentally sends stop.

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


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/4cb51fade656ee80. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/plugins/computer-use/src/tools.mjs:796

      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;
      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)})`);

View on GitHub (pinned to 73e0f67d83)