vitest-dev/vitest · error · Error

Cannot find iframe with id

Error message

Cannot find iframe with id ${event.iframeId}

What it means

The browser orchestrator multiplexes tests across iframes keyed by iframeId. sendEventToIframe looks up the iframe in this.iframes; if it was removed (removeIframe deletes the entry) or never registered, it throws. Messages are dispatched to tester iframes during normal test execution (prepare, run, collect).

Solutions

  1. Avoid navigating/reloading the iframe from test code: call `event.preventDefault()` on form submits and use memory-based routing for SPA routers.
  2. Ensure dependencies are optimized (configure `optimizeDeps`) so the tester iframe does not reload.
  3. If seen sporadically in CI, check for tester crashes/unhandled errors that remove the iframe.
  4. Report persistent occurrences with a reproduction — this often indicates a race the orchestrator should tolerate.

Example fix

// before
form.dispatchEvent(new Event('submit')) // browser reloads iframe -> orchestrator removes it

// after
form.addEventListener('submit', (e) => e.preventDefault())
form.dispatchEvent(new Event('submit'))
Defensive patterns

Strategy: try-catch

Validate before calling

// there is no public pre-check; reduce likelihood by avoiding iframe reloads:
form.addEventListener('submit', (e) => e.preventDefault())
await expect(page.getByRole('button')).toBeVisible() // wait for tester readiness

Try / catch

// orchestrator-internal; if surfacing in custom UI integration:
try {
  await sendEventToIframe(event)
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Cannot find iframe')) {
    // iframe was removed; re-register or skip this event
    return
  }
  throw err
}

Prevention

When it happens

Trigger: The orchestrator tries to send an event (prepare/run/etc.) to an iframe that has been removed (tester crashed, reloaded, or was torn down) or whose id was never registered (typo, race during registration). Common when an iframe reloads mid-test and is removed before a queued message is dispatched.

Common situations: Iframe navigated/reloaded during a test (e.g., form submit without preventDefault, router location change) triggering removal; tester crash; timing race where an event is queued before the iframe's onload registers it.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/e17be4af39f7bef8. Report an issue: GitHub.

Appendix: source

Thrown at packages/browser/src/client/orchestrator.ts:486

        }

        await client.rpc.onUnhandledError(
          {
            name: 'Unexpected Event',
            message: `Unexpected event: ${(e.data as any).event}`,
          },
          'Unexpected Event',
        )
      }
    }
  }

  private iframeEvents = new WeakMap<HTMLIFrameElement, Set<string>>()

  private async sendEventToIframe(event: IframeChannelOutgoingEvent): Promise<void> {
    const iframe = this.iframes.get(event.iframeId)
    if (!iframe) {
      throw new Error(`Cannot find iframe with id ${event.iframeId}`)
    }
    let events = this.iframeEvents.get(iframe)
    if (!events) {
      events = new Set()
      this.iframeEvents.set(iframe, events)
    }
    events.add(event.event)

    const messageId = this.messageId++
    channel.postMessage({ ...event, messageId } satisfies IframeReceivedEvent)

    return new Promise<void>((resolve, reject) => {
      let ackTimer: ReturnType<typeof setTimeout>

      const cleanupEvents = () => {
        clearTimeout(ackTimer)
        channel.removeEventListener('message', onReceived)
        this.eventTarget.removeEventListener('iframeerror', onError)

View on GitHub (pinned to 1fa9837ec2)