jackwener/OpenCLI · error

Element not found: ref=${ref}

Error message

Element not found: ref=${ref}

What it means

scrollToRefJs builds an in-page script that resolves an element by its snapshot ref attribute (data-opencli-ref or data-ref) and scrolls it into view. If no element with that ref exists in the current document, the injected script throws 'Element not found: ref=<ref>'.

Source

Thrown at src/browser/dom-snapshot.ts:85

  /** Previous snapshot hash set (JSON array of hashes) for diff marking (default null) */
  previousHashes?: string | null;
}

// ─── Utility JS Generators ───────────────────────────────────────────

/**
 * Generate JS to scroll to an element identified by data-opencli-ref.
 * Completes the snapshot→action loop: snapshot identifies `[3]<button>`,
 * caller can then `scrollToRef('3')` to bring it into view.
 */
export function scrollToRefJs(ref: string): string {
  const safeRef = JSON.stringify(ref);
  return `
    (() => {
      const ref = ${safeRef};
      const el = document.querySelector('[data-opencli-ref="' + ref + '"]')
        || document.querySelector('[data-ref="' + ref + '"]');
      if (!el) throw new Error('Element not found: ref=' + ref);
      el.scrollIntoView({ behavior: 'smooth', block: 'center', inline: 'nearest' });
      return { scrolled: true, tag: el.tagName.toLowerCase(), text: (el.textContent || '').trim().slice(0, 80) };
    })()
  `.trim();
}

/**
 * Generate JS to extract all form field values from the page.
 * Returns structured JSON: { forms: [{ id, action, fields: [{ tag, type, name, value, ... }] }] }
 */
export function getFormStateJs(): string {
  return `
    (() => {
      const result = { forms: [], orphanFields: [] };

      // Collect all forms
      for (const form of document.forms) {
        const formData = {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-take the DOM snapshot to obtain fresh refs and retry with the new ref
  2. Verify you are targeting the same tab/frame the snapshot came from
  3. Guard the call in try/catch and fall back to re-snapshotting when the ref is stale

Example fix

// before
await page.scroll(refFromOldSnapshot);
// after
const snap = await page.snapshot();
await page.scroll(snap.refOfElement);
Defensive patterns

Strategy: try-catch

Validate before calling

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

Type guard

function isRefLive(exists: boolean): boolean { return exists === true; }

Try / catch

try { await page.scroll(ref); }
catch (e) {
  if (String(e.message).startsWith('Element not found')) {
    await page.snapshot();
    ref = /* fresh ref */;
    await page.scroll(ref);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling scroll (via js/scrollToRefJs) with a ref string that does not match any element carrying data-opencli-ref/data-ref — typically a stale ref from a previous snapshot or a snapshot taken in a different frame/page.

Common situations: The page navigated or re-rendered after the DOM snapshot was taken, invalidating refs; using a ref from another tab/iframe; typo in the ref value.

Related errors


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