microsoft/playwright · error · ValidationError
${path}: object with guid ${guid} has type ${dispatcher._typ
Error message
${path}: object with guid ${guid} has type ${dispatcher._type}, expected ${names.toString()} What it means
ValidationError raised in _tChannelImplFromWire when the guid resolves to a Dispatcher but its _type is not in the accepted names list for that parameter. The wire validator expects a specific channel type (e.g. 'Page', 'Frame', 'ElementHandle'); receiving a different but existing handle type is rejected. The message names the actual type and the expected types to pinpoint the mismatch.
Source
Thrown at packages/playwright-core/src/server/dispatchers/dispatcher.ts:250
};
}
private _validatorFromWireContext(): ValidatorContext {
return {
tChannelImpl: this._tChannelImplFromWire.bind(this),
binary: this._isInProcess ? 'buffer' : 'fromBase64',
isUnderTest,
};
}
private _tChannelImplFromWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext): any {
if (arg && typeof arg === 'object' && typeof arg.guid === 'string') {
const guid = arg.guid;
const dispatcher = this._dispatcherByGuid.get(guid);
if (!dispatcher)
throw new ValidationError(`${path}: no object with guid ${guid}`);
if (names !== '*' && !names.includes(dispatcher._type))
throw new ValidationError(`${path}: object with guid ${guid} has type ${dispatcher._type}, expected ${names.toString()}`);
return dispatcher;
}
throw new ValidationError(`${path}: expected guid for ${names.toString()}`);
}
private _tChannelImplToWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext): any {
if (arg instanceof Dispatcher) {
if (names !== '*' && !names.includes(arg._type))
throw new ValidationError(`${path}: dispatcher with guid ${arg._guid} has type ${arg._type}, expected ${names.toString()}`);
return { guid: arg._guid };
}
throw new ValidationError(`${path}: expected dispatcher ${names.toString()}`);
}
existingDispatcher<DispatcherType>(object: any): DispatcherType | undefined {
return this._dispatcherByObject.get(object) as DispatcherType | undefined;
}
View on GitHub (pinned to c8fc3bf8d3)
Solutions
- Send the exact handle type the method's channel signature declares (see channels.d.ts / protocol.yml).
- Add type checks on the client side before sending: assert(handle._type === 'Page') or use the typed client API which encodes the constraint.
- Double-check refactors that touch handle plumbing — the guid is fine but the type is wrong.
Example fix
// before: sending a Page where a Frame is required
await connection.send('frame', 'click', { frame: page });
// after: pass the correct type
await connection.send('frame', 'click', { frame: page.mainFrame() }); Defensive patterns
Strategy: type-guard
Validate before calling
// Validate handle type before sending.
function assertChannel(handle: { _type?: string }, expected: string[]) {
if (!handle || !expected.includes(handle._type!))
throw new Error(`Expected ${expected.join('|')}, got ${handle?._type}`);
} Type guard
function isChannelOf<T extends { _type: string }>(h: any, types: readonly string[]): h is T {
return !!h && typeof h._type === 'string' && types.includes(h._type);
} Prevention
- Use the typed client API which encodes channel-type constraints at compile time.
- When refactoring handle plumbing, double-check the channel type each method expects.
- Cross-reference channels.d.ts / protocol.yml when building raw messages.
When it happens
Trigger: Passing a Page where a Frame is required, an ElementHandle where a JSHandle is required, a BrowserType where a Browser is required, etc. — i.e. a valid handle of the wrong channel type. Common with hand-rolled protocol clients or dynamic dispatch that picks the wrong handle variable.
Common situations: Custom protocol/transport code that confuses similar handle types (Page vs Frame, ElementHandle vs JSHandle, Request vs Response); refactors that change a field but leave the wrong handle being sent.
Related errors
- ${path}: expected channel ${names.toString()}
- ${path}: no object with guid ${guid}
- ${path}: expected guid for ${names.toString()}
- ${path}: dispatcher with guid ${arg._guid} has type ${arg._t
- ${path}: expected channel ${names.toString()}
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/a8f1595db3c67fae.
Report an issue: GitHub.