stablyai/orca · warning · BrowserError

browser_ref_not_found

browser_ref_not_found

Error message

Element ref ${ref} was not found. Run 'orca snapshot' to see available refs.

What it means

The ref string provided to resolveRef() is not a key in the current snapshot's refMap. The element either wasn't captured in the snapshot (e.g., it was in a collapsed subtree or aria-hidden region excluded from the AX tree), or the ref value originates from a different/older snapshot whose refs no longer apply. This is distinct from browser_stale_ref (812) which means no snapshot exists at all.

Source

Thrown at src/main/browser/cdp-bridge.ts:1360

  private async resolveRef(
    guest: Electron.WebContents,
    sender: CdpCommandSender,
    ref: string
  ): Promise<RefEntry> {
    const tabId = this.resolveTabId(guest.id)
    const state = this.getOrCreateTabState(tabId)

    if (!state.snapshotResult) {
      throw new BrowserError(
        'browser_stale_ref',
        "No snapshot exists for this tab. Run 'orca snapshot' first."
      )
    }

    const entry = state.snapshotResult.refMap.get(ref)
    if (!entry) {
      throw new BrowserError(
        'browser_ref_not_found',
        `Element ref ${ref} was not found. Run 'orca snapshot' to see available refs.`
      )
    }

    // Why: iframe refs use a child session with independent nav history, so a parent-navId check would falsely reject them.
    if (!entry.sessionId) {
      const currentNavId = await this.getNavigationId(sender)
      if (state.navigationId && currentNavId !== state.navigationId) {
        state.snapshotResult = null
        state.navigationId = null
        throw new BrowserError(
          'browser_stale_ref',
          "The page has navigated since the last snapshot. Run 'orca snapshot' to get fresh refs."
        )
      }
    }

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Run 'orca snapshot' and use only refs from the latest snapshot result.
  2. Do not cache or hardcode refs across navigations or snapshots.
  3. Verify the target element is visible and present in the AX tree before referencing it.

Example fix

// before
await bridge.click('old-ref-from-previous-snapshot')

// after
const snap = await bridge.snapshot()
const ref = snap.refs.find(r => r.role === 'button' && r.name === 'Submit')?.ref
if (!ref) throw new Error('Submit button not found in snapshot')
await bridge.click(ref)
Defensive patterns

Strategy: validation

Validate before calling

const snap = await bridge.snapshot()
const refEntry = snap.refs.find(r => r.ref === ref)
if (!refEntry) {
  throw new Error(`Ref ${ref} not in current snapshot. Available: ${snap.refs.map(r => r.ref).join(', ')}`)
}
await bridge.click(ref)

Try / catch

try {
  await bridge.click(ref)
} catch (e) {
  if (e instanceof BrowserError && e.code === 'browser_ref_not_found') {
    const snap = await bridge.snapshot()
    const fresh = snap.refs.find(r => r.role === desiredRole && r.name === desiredName)
    if (fresh) await bridge.click(fresh.ref)
    else throw e
  }
  throw e
}

Prevention

When it happens

Trigger: Using a ref from a previous snapshot after a new snapshot was taken; referencing an element that was hidden/collapsed and excluded from the AX snapshot; typo or truncation in the ref string.

Common situations: Agent caches refs across snapshots; element is in a shadow DOM or aria-hidden region the AX tree omits; ref string was copy-pasted incorrectly.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/49bd183ee27595bf. Report an issue: GitHub.