Hmbown/CodeWhale · error

browser action "type" requires text

Error message

browser action "type" requires text

What it means

Validation error from the browser action resolver in resolveTool: the 'type' action maps to browser_type and must carry the text to type into the focused page element. It fires when the text field is absent, not a string, or a zero-length string, meaning a keystroke-injection request with no payload.

Solutions

  1. Pass text as a non-empty string, e.g. {action:"type", text:"hello"}.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at crates/tui/plugins/computer-use/src/tools.mjs:850 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

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

      switch (args.action) {
        case "start":
          if (rest.url != null && typeof rest.url !== "string") throw bad("browser start url must be a string");
          return { name: "browser_start", args: rest };
        case "status": return { name: "browser_status", args: rest };
        case "navigate":
          if (typeof rest.url !== "string" || !rest.url.trim()) throw bad('browser action "navigate" requires url');
          return { name: "browser_navigate", args: rest };
        case "click": {
          const hasSelector = typeof rest.selector === "string" && rest.selector.trim();
          const hasPoint = rest.point != null && Number.isFinite(rest.point?.x) && Number.isFinite(rest.point?.y);
          if (hasSelector && hasPoint) throw bad('browser action "click" takes selector or point, not both — pick one target');
          if (!hasSelector && !hasPoint) throw bad('browser action "click" needs selector (CSS) or point {x,y}');
          if (!hasSelector) delete rest.selector;
          if (!hasPoint) delete rest.point;
          return { name: "browser_click", args: rest };
        }
        case "type":
          if (typeof rest.text !== "string" || !rest.text.length) throw bad('browser action "type" requires text');
          return { name: "browser_type", args: rest };
        case "screenshot": return { name: "browser_screenshot", args: rest };
        case "stop": return { name: "browser_stop", args: rest };
        default:
          throw bad(`browser action must be start, status, navigate, click, type, screenshot or stop (got ${JSON.stringify(args.action)})`);
      }
    }
    case "trajectory": {
      const rest = { ...args };
      delete rest.action;
      switch (args.action) {
        case "start": return { name: "trajectory_start", args: rest };
        case "stop": return { name: "trajectory_stop", args: rest };
        case "status": return { name: "trajectory_status", args: rest };
        case "replay": return { name: "trajectory_replay", args: rest };
        default:
          throw bad(`trajectory action must be start, stop, status or replay (got ${JSON.stringify(args.action)})`);
      }

View on GitHub (pinned to 73e0f67d83)