microsoft/playwright · error · Error

Cannot find command to respond: ${id}

Error message

Cannot find command to respond: ${id}

What it means

Thrown in dispatch() when a response message arrives with an id that has no entry in _callbacks (after the _closedError guard). The callback was either already invoked and deleted, or the callbacks map was cleared. This is an internal protocol-consistency violation: the server produced a response the client was no longer expecting.

Source

Thrown at packages/playwright-core/src/client/connection.ts:244

  private _validatorFromWireContext(): ValidatorContext {
    return {
      tChannelImpl: this._tChannelImplFromWire.bind(this),
      binary: this._rawBuffers ? 'buffer' : 'fromBase64',
      isUnderTest,
    };
  }

  dispatch(message: object) {
    if (this._closedError)
      return;

    const { id, guid, method, params, result, error, errorDetails, log } = message as any;
    if (id) {
      if (debugLogger.isEnabled('channel'))
        debugLogger.log('channel', '<RECV ' + JSON.stringify(message));
      const callback = this._callbacks.get(id);
      if (!callback)
        throw new Error(`Cannot find command to respond: ${id}`);
      this._callbacks.delete(id);
      if (error && !result) {
        const parsedError = parseError(error);
        if (callback.signal?.aborted && parsedError instanceof AbortError)
          parsedError.cause = callback.signal.reason;
        parsedError.log = log || [];
        rewriteErrorMessage(parsedError, parsedError.message + formatCallLog(log));
        const detailsValidator = maybeFindValidator(callback.type, callback.method, 'ErrorDetails');
        if (detailsValidator)
          parsedError.details = detailsValidator(errorDetails ?? {}, '', this._validatorFromWireContext());
        callback.reject(parsedError);
      } else {
        const validator = findValidator(callback.type, callback.method, 'Result');
        callback.resolve(validator(result, '', this._validatorFromWireContext()));
      }
      return;
    }

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Confirm you are using the same Playwright version on client and server.
  2. If you are behind a proxy/custom WebSocket transport, check it for message duplication or reordering.
  3. Capture a 'channel' debug log (DEBUG=pw:channel) to confirm duplicate/out-of-order responses.
  4. Report with the reproduction if it persists against an unmodified server — this should not happen in normal operation.
Defensive patterns

Strategy: try-catch

Try / catch

// This is an internal protocol error — wrap the broad operation, log, and reconnect.
try {
  await page.someMethod();
} catch (e) {
  if (/Cannot find command to respond/.test(String(e?.message))) {
    // Transport/server produced a duplicate or out-of-order response.
    // Only sane recovery is a fresh connection.
    await reconnect();
  } else throw e;
}

Prevention

When it happens

Trigger: Server sends a duplicate response for an id; a response arrives after the callback was already resolved/rejected; race between an in-flight request and connection teardown where the map was cleared; a custom transport replays or reorders messages. Practically unreachable in normal use — it indicates transport/server bugs or message duplication.

Common situations: Misbehaving proxy or custom transport that duplicates frames; running an experimental/patched server; extremely rare races under heavy message volume; using an unofficial server implementation.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/8a067cad01a5f59a. Report an issue: GitHub.