vitest-dev/vitest · error · Error

Tester RPC " " was not established.

Error message

Tester RPC "${rpcId}" was not established.

What it means

After obtaining a CDPSession, ensureCDPHandler looks up the corresponding tester RPC connection in (browser.state as BrowserServerState).testers using rpcId. The testers map is populated when a tester iframe connects over WebSocket. If no tester has registered under that rpcId, the CDP handler cannot be wired to a target page.

Solutions

  1. Reload the tester iframe so it reconnects and re-registers under its rpcId before issuing CDP commands.
  2. Check the browser console and server logs for tester load failures (module errors, 404s) that prevent WS registration.
  3. Verify rpcId is the current tester's id, not a stale one from a previous run.
  4. Ensure no middleware/proxy strips the WS upgrade between the tester and the Vitest server.

Example fix

// before
const handler = await parent.ensureCDPHandler(sessionId, staleRpcId)
// after - read the live rpc id from the testers map
const rpcId = [...(browser.state as BrowserServerState).testers.keys()][0]!
const handler = await parent.ensureCDPHandler(sessionId, rpcId)
Defensive patterns

Strategy: validation

Validate before calling

function testerRpcLive(testers: Map<string, unknown>, rpcId: string): boolean {
  return testers.has(rpcId)
}

Prevention

When it happens

Trigger: Issuing a CDP request for an rpcId whose tester WebSocket never connected, already disconnected, or connected under a different rpcId. Common during flaky loads, navigation away from the tester iframe, or when the tester crashed before registering.

Common situations: Browser UI issuing CDP commands before the tester finished loading; tester crashed on a syntax error so no WS connection was made; network/proxy issue dropping the tester WS handshake; reusing an rpcId from a previous run.

Related errors


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

Appendix: source

Thrown at packages/browser/src/node/projectParent.ts:221

    const provider = browser.provider
    if (!provider) {
      throw new Error(`Browser provider is not defined for the project "${browserSession.project.name}".`)
    }
    if (!provider.getCDPSession) {
      throw new Error(`CDP is not supported by the provider "${provider.name}".`)
    }

    const session = await this.cdpSessionsPromises.get(rpcId) ?? await (async () => {
      const promise = provider.getCDPSession!(sessionId).finally(() => {
        this.cdpSessionsPromises.delete(rpcId)
      })
      this.cdpSessionsPromises.set(rpcId, promise)
      return promise
    })()

    const rpc = (browser.state as BrowserServerState).testers.get(rpcId)
    if (!rpc) {
      throw new Error(`Tester RPC "${rpcId}" was not established.`)
    }

    const handler = new BrowserServerCDPHandler(session, rpc)
    this.cdps.set(
      rpcId,
      handler,
    )
    return handler
  }

  removeCDPHandler(sessionId: string): void {
    this.cdps.delete(sessionId)
  }

  async formatScripts(scripts: BrowserScript[] | undefined): Promise<HtmlTagDescriptor[]> {
    if (!scripts?.length) {
      return []
    }

View on GitHub (pinned to 1fa9837ec2)