jackwener/OpenCLI · error

Element not found: ${safeRef}

Error message

Element not found: ${safeRef}

What it means

As the final fallback in clickWithQuads, an in-page evaluate() queries the element by its data-opencli-ref and throws 'Element not found: <ref>' if the ref no longer resolves in the live document.

Source

Thrown at src/browser/page.ts:403

      // Try getBoxModel
      try {
        const box = await this.cdp('DOM.getBoxModel', { nodeId }) as { model: { content: number[] } };
        if (box.model?.content) {
          const c = box.model.content;
          const cx = (c[0] + c[2] + c[4] + c[6]) / 4;
          const cy = (c[1] + c[3] + c[5] + c[7]) / 4;
          await this.nativeClick(Math.round(cx), Math.round(cy));
          return;
        }
      } catch { /* fallthrough */ }
    } catch { /* fallthrough */ }

    // Final fallback: regular click
    await this.evaluate(`
      (() => {
        const el = document.querySelector('[data-opencli-ref="' + ${safeRef} + '"]');
        if (!el) throw new Error('Element not found: ' + ${safeRef});
        el.click();
        return 'clicked';
      })()
    `);
  }

}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-take the DOM snapshot and retry with a fresh ref
  2. Perform navigation/re-render then re-resolve the element before clicking
  3. Add a wait/retry loop that re-snapshots on ref-not-found

Example fix

// before
await page.clickWithQuads(staleRef, ...);
// after
try { await page.clickWithQuads(staleRef, ...); }
catch { const snap = await page.snapshot(); await page.clickWithQuads(snap.refFor('Submit'), ...); }
Defensive patterns

Strategy: retry

Validate before calling

const exists = await page.evaluate(`!!document.querySelector('[data-opencli-ref="${ref}"]')`);
if (!exists) await page.snapshot(); // refresh before retry

Type guard

function refResolves(found: Element | null): found is Element { return found !== null; }

Try / catch

try { await page.clickWithQuads(ref, ...); }
catch (e) {
  if (String(e.message).startsWith('Element not found')) {
    const snap = await page.snapshot();
    await page.clickWithQuads(snap.refFor(label), ...);
  } else throw e;
}

Prevention

When it happens

Trigger: clickWithQuads reached the evaluate fallback (earlier strategies failed) and the ref attribute no longer exists — the page re-rendered or navigated after the snapshot was captured.

Common situations: SPAs re-rendering lists and regenerating refs; navigation triggered by a prior click; long-lived sessions where snapshots are minutes old.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/cf78d156ca1f0cb5. Report an issue: GitHub.