can1357/oh-my-pi · warning
mouse action must be a string
Error message
mouse action must be a string
What it means
In the debug server's 'mouse' command handler, 'request.action' defaults to 'click' when undefined, but if it is present and not a string, this error is thrown before any mouse sequence is injected. The debug protocol only accepts known string actions (e.g. click, move, drag).
Source
Thrown at packages/tui/src/debug-server.ts:370
case "keys": {
if (typeof request.keys !== "string") throw new Error("keys must be a string");
const parsed = parseKeyTokens(request.keys);
for (const sequence of parsed.sequences) this.#tui.injectDebugInput(sequence);
return { ok: true, injected: parsed.events };
}
case "bytes":
if (typeof request.data !== "string") throw new Error("data must be a string");
this.#tui.injectDebugInput(request.data);
return { ok: true };
case "paste":
if (typeof request.text !== "string") throw new Error("text must be a string");
this.#tui.injectDebugInput(`\x1b[200~${request.text}\x1b[201~`);
return { ok: true };
case "mouse": {
if (typeof request.x !== "number" || typeof request.y !== "number")
throw new Error("mouse x and y must be numbers");
const action = request.action === undefined ? "click" : request.action;
if (typeof action !== "string") throw new Error("mouse action must be a string");
this.#tui.injectDebugInput(mouseSequence(request.x, request.y, action));
return { ok: true };
}
case "quit":
return { ok: true };
default:
return { ok: false, error: `unknown op ${request.op}` };
}
}
#node(component: Component): TuiDebugTreeNode {
const children = componentChildren(component);
const focusable = isFocusable(component);
return {
kind: componentKind(component),
...(component.debugId === undefined ? {} : { id: component.debugId }),
...(focusable ? { focusable: true, focused: component === this.#tui.getFocused() } : {}),
...(children.length === 0 ? {} : { children: children.map(child => this.#node(child)) }),View on GitHub (pinned to 9690622007)
Solutions
- Send 'action' as a string (or omit it entirely to get the 'click' default).
- Map numeric enum actions to their string names on the client before sending.
- Ensure the action is a valid action name accepted by mouseSequence (e.g. "click").
- Remove the 'action': null field explicitly rather than sending null.
Example fix
// before
await send({ method: "mouse", x: 10, y: 20, action: MouseButton.Left }); // number
// after
await send({ method: "mouse", x: 10, y: 20, action: "click" }); // or omit action Defensive patterns
Strategy: validation
Validate before calling
const ACTIONS = new Set(["click", "move", "drag"]);
if (typeof action === "string" && ACTIONS.has(action)) {
await send({ method: "mouse", x, y, action });
} // or omit action to default to "click" Type guard
function isMouseAction(v: unknown): v is string {
return typeof v === "string";
} Try / catch
try {
await send({ method: "mouse", x, y, action });
} catch (err) {
if (err instanceof Error && err.message === "mouse action must be a string") {
console.error(`invalid mouse action: ${JSON.stringify(action)}`);
} else throw err;
} Prevention
- Omit the action field to use the 'click' default instead of passing null/undefined-like values.
- Keep action as a string enum on the client; serialize enum members to their string names.
- Never send null for optional fields — delete the key instead.
When it happens
Trigger: Sending a debug 'mouse' request where 'action' is a number, boolean, null, or an object — e.g. {"method":"mouse","x":10,"y":20,"action":1} or "action":null. Note explicit null is NOT treated as undefined, so it fails.
Common situations: Clients that serialize the action field from an enum as a number; passing a null from a JS client (null !== undefined); typos producing undefined is fine but a mistyped variable holding a non-string slips through.
Related errors
- mouse x and y must be numbers
- Invalid package name: ${name}
- Invalid package name: ${name}
- Invalid log regex: ${error instanceof Error ? error.message
- Daemon name must be 1-48 letters, numbers, dots, underscores
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/b19669a87b404ab1.
Report an issue: GitHub.