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
- Confirm you are using the same Playwright version on client and server.
- If you are behind a proxy/custom WebSocket transport, check it for message duplication or reordering.
- Capture a 'channel' debug log (DEBUG=pw:channel) to confirm duplicate/out-of-order responses.
- 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
- Use the bundled transport; avoid custom WebSocket proxies that duplicate frames.
- Keep client and server on identical Playwright versions.
- Enable DEBUG=pw:channel in CI to capture protocol anomalies early.
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
- Cannot find object to "${method}": ${guid}
- Unknown new child: ${params.guid}
- Cannot find parent object ${parentGuid} to create ${guid}
- Object with guid ${arg.guid} was not bound in the connection
- ${path}: expected channel ${names.toString()}
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/8a067cad01a5f59a.
Report an issue: GitHub.