openclaw - ✅(Solved) Fix NaN coordinates propagated silently in click-coords command [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#83876Fetched 2026-05-20 03:47:51
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
1
Timeline (top)
labeled ×5commented ×1cross-referenced ×1

Error Message

x and y are parsed with bare Number() from positional string arguments without a Number.isFinite guard. If a user passes a non-numeric string (e.g. typo or shell interpolation gone wrong), x and y will be NaN. NaN serializes to null in JSON, so the server receives {x: null, y: null} instead of a clear error. The codebase already applies Number.isFinite guards to optional numeric options (delayMs on line 99, timeoutMs elsewhere), making this inconsistency observable. The resize command has the same issue: its argument parsers use (v: string) => Number(v) without finitude checks, so NaN can also propagate there. Add Number.isFinite checks for x and y before building the body and emit a user-facing error (danger + exit 1) on failure, consistent with how timeoutMs is guarded elsewhere. Same fix needed for the resize command's width/height arguments. it('rejects non-numeric coordinates with an error', async () => { expect(getBrowserCliRuntime().error).toHaveBeenCalledWith(expect.stringContaining('invalid')); register.element.ts click-coords action handler: add Number.isFinite(x) && Number.isFinite(y) guard and error path before runElementAction call. Mirror for resize in register.navigation.ts.

Fix Action

Fix / Workaround

Severity: medium / Confidence: high / Category: bug Triage: confirmed-bug Detected against: openclaw v2026.5.18 (latest stable at time of scan, 2026-05-18) Tooling: clawpatch 0.3.0 + acpx/claude-sonnet-4-5 via Brad Mills protocol


Standardized clawpatch finding. Persistent in v2026.5.18 (not resolved by upgrading from v2026.5.12). Finding ID: fnd_sig-feat-cli-command-0029f9d57b-_0191f13e15.

PR fix notes

PR #84208: fix(browser-cli): reject non-numeric coordinates in click-coords and resize (#83876)

Description (problem / solution / changelog)

Fixes #83876.

browser click-coords <x> <y> (extensions/browser/src/cli/browser-cli-actions-input/register.element.ts:88-89) and browser resize <width> <height> (register.navigation.ts:50) parse their positional numeric arguments with bare Number(). A non-numeric input — typo, an unintended shell expansion, an empty string — yields NaN, which JSON.stringify serializes as null. The CLI happily forwards { kind: "clickCoords", x: null, y: 200 } to the /act endpoint instead of failing fast with a user-visible error. The surrounding option parsers in the same files already use Number.isFinite for exactly this reason (delayMs at line 99, timeoutMs at line 175, the geolocation triple in browser-cli-state.ts:187-189); the positional args were the missing case.

Changes

  • extensions/browser/src/cli/browser-cli-actions-input/register.element.ts: guard the click-coords action handler with if (!Number.isFinite(x) || !Number.isFinite(y)) and emit defaultRuntime.error(danger("invalid coordinates …")) + defaultRuntime.exit(1) before runElementAction is called. Mirrors the existing defaultRuntime.error(danger(...)) + exit(1) pattern in register.navigation.ts's navigate error branch.
  • extensions/browser/src/cli/browser-cli-actions-input/register.navigation.ts: identical guard on the resize action handler against width and height, before runBrowserResizeWithOutput.

Diff stat: 2 files, +14 / -0. No behavior change for any input that was already a finite number.

Real behavior proof

  • Behavior or issue addressed: Sanitized issue evidence — runElementAction posts body to /act via callBrowserAct, and runBrowserResizeWithOutput posts { width, height, … } via the resize helper. JSON-stringifying NaN produces null, so the server can't distinguish "missing field" from "user typo'd the argument." The guard runs at the CLI boundary and never sends the malformed body.

  • Real environment tested: Local Node 22.x. Probe at /tmp/probe_83876.mjs does both halves of the proof. (a) Parses the patched register.element.ts and register.navigation.ts and verifies (i) each action handler now contains Number.isFinite on its positional args + defaultRuntime.error(danger(...)) + defaultRuntime.exit(1), and (ii) the guard precedes the request call (runElementAction / runBrowserResizeWithOutput). (b) Replays both shapes in pure JS — buggy handler with "abc" "200" returns a payload containing "x":null (confirming the exact #83876 symptom: NaN → JSON null → silent transmission to the server); patched handler with the same input returns { sent: false, exitCode: 1 } (rejected at the CLI boundary, request never issued); patched handler with valid "100" "200" returns "x":100,"y":200 unchanged (no regression).

  • Exact steps or command run after this patch: node /tmp/probe_83876.mjs

  • Evidence after fix:

PASS: click-coords action guards x/y with Number.isFinite and emits danger+exit(1)
PASS: click-coords guard runs BEFORE runElementAction (rejects before request)
PASS: resize action guards width/height with Number.isFinite and emits danger+exit(1)
PASS: resize guard runs BEFORE runBrowserResizeWithOutput (rejects before request)
PASS: replay (buggy): non-numeric x silently serializes to JSON null and is sent to /act — confirms #83876
PASS: replay (patched): non-numeric x is rejected before /act with exit(1) — request never sent
PASS: replay (patched, valid input): finite numerics flow through unchanged — no regression

ALL CASES PASS
  • Observed result after fix: browser click-coords abc 200 now writes invalid coordinates "abc 200": x and y must be finite numbers to stderr and exits 1 instead of POSTing { x: null, y: 200 } to /act. browser resize abc 100 likewise rejects on the CLI side. Any finite numeric input — including 0, negative, decimals — is unchanged.

  • What was not tested: No live browser session against a Chrome/CDP target — that's outside the scope of an input-validation fix. The probe replays the exact NaN-to-null serialization path called out in the issue's repro section.

Audit (per CLAUDE rules — all 5 steps)

  • Existing-helper check: No helper needed — Number.isFinite is the codebase's established predicate for this exact concern (delayMs at register.element.ts:99, timeoutMs at :175, three coords in browser-cli-state.ts:187-189, the resolved-timeout pair in browser-cli-shared.ts:40,46). I'm reusing the same predicate, not inventing one. PASS
  • Shared-helper caller check: No shared helper is being modified. The two action handlers are leaf endpoints in their respective command registrations; the new validation is local to each action and cannot affect other call sites. PASS
  • Broader-fix rival scan: gh pr list --search '83876 in:title,body' and gh pr list --search 'click-coords coordinates in:title,body' return no open PRs. Issue timeline shows zero cross-references. PASS
  • Recent-merge audit: git log --oneline -5 -- extensions/browser/src/cli/browser-cli-actions-input/ shows no recent commits touching these files. PASS
  • Prototype-pollution scan: N/A — Number.isFinite on locally-bound numeric variables, no object property access.

Changed files

  • extensions/browser/src/cli/browser-cli-actions-input/register.element.ts (modified, +7/-0)
  • extensions/browser/src/cli/browser-cli-actions-input/register.navigation.ts (modified, +7/-0)

Code Example

const x = Number(xRaw);
      const y = Number(yRaw);
      await runElementAction({
        cmd,
        body: {
          kind: "clickCoords",
          x,
          y,
          ...
          delayMs: Number.isFinite(opts.delayMs) ? opts.delayMs : undefined,
RAW_BUFFERClick to expand / collapse

Severity: medium / Confidence: high / Category: bug Triage: confirmed-bug Detected against: openclaw v2026.5.18 (latest stable at time of scan, 2026-05-18) Tooling: clawpatch 0.3.0 + acpx/claude-sonnet-4-5 via Brad Mills protocol

Evidence

  • extensions/browser/src/cli/browser-cli-actions-input/register.element.ts:88-99 (click-coords action)
const x = Number(xRaw);
      const y = Number(yRaw);
      await runElementAction({
        cmd,
        body: {
          kind: "clickCoords",
          x,
          y,
          ...
          delayMs: Number.isFinite(opts.delayMs) ? opts.delayMs : undefined,

Reasoning

x and y are parsed with bare Number() from positional string arguments without a Number.isFinite guard. If a user passes a non-numeric string (e.g. typo or shell interpolation gone wrong), x and y will be NaN. NaN serializes to null in JSON, so the server receives {x: null, y: null} instead of a clear error. The codebase already applies Number.isFinite guards to optional numeric options (delayMs on line 99, timeoutMs elsewhere), making this inconsistency observable. The resize command has the same issue: its argument parsers use (v: string) => Number(v) without finitude checks, so NaN can also propagate there.

Reproduction

browser click-coords abc 200 → sends {kind:'clickCoords', x: null, y: 200} to /act (JSON serialization of NaN is null)

Recommendation

Add Number.isFinite checks for x and y before building the body and emit a user-facing error (danger + exit 1) on failure, consistent with how timeoutMs is guarded elsewhere. Same fix needed for the resize command's width/height arguments.

Why existing tests miss this

No CLI-level test exists for click-coords or resize; the test files only cover download timing and dialog conflict validation.

Suggested regression test

it('rejects non-numeric coordinates with an error', async () => { const program = createActionInputProgram(); await program.parseAsync(['browser', 'click-coords', 'abc', '200'], { from: 'user' }); expect(getBrowserCliRuntime().error).toHaveBeenCalledWith(expect.stringContaining('invalid')); expect(mocks.callBrowserRequest).not.toHaveBeenCalled(); });

Minimum fix scope

register.element.ts click-coords action handler: add Number.isFinite(x) && Number.isFinite(y) guard and error path before runElementAction call. Mirror for resize in register.navigation.ts.


Standardized clawpatch finding. Persistent in v2026.5.18 (not resolved by upgrading from v2026.5.12). Finding ID: fnd_sig-feat-cli-command-0029f9d57b-_0191f13e15.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix NaN coordinates propagated silently in click-coords command [1 pull requests, 1 comments, 2 participants]