{"record":{"id":"a8f1595db3c67fae","repo":"microsoft/playwright","slug":"path-object-with-guid-guid-has-type-dispa","errorCode":null,"errorMessage":"${path}: object with guid ${guid} has type ${dispatcher._type}, expected ${names.toString()}","messagePattern":"(.+?): object with guid (.+?) has type (.+?), expected (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/dispatchers/dispatcher.ts","lineNumber":250,"sourceCode":"    };\n  }\n\n  private _validatorFromWireContext(): ValidatorContext {\n    return {\n      tChannelImpl: this._tChannelImplFromWire.bind(this),\n      binary: this._isInProcess ? 'buffer' : 'fromBase64',\n      isUnderTest,\n    };\n  }\n\n  private _tChannelImplFromWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext): any {\n    if (arg && typeof arg === 'object' && typeof arg.guid === 'string') {\n      const guid = arg.guid;\n      const dispatcher = this._dispatcherByGuid.get(guid);\n      if (!dispatcher)\n        throw new ValidationError(`${path}: no object with guid ${guid}`);\n      if (names !== '*' && !names.includes(dispatcher._type))\n        throw new ValidationError(`${path}: object with guid ${guid} has type ${dispatcher._type}, expected ${names.toString()}`);\n      return dispatcher;\n    }\n    throw new ValidationError(`${path}: expected guid for ${names.toString()}`);\n  }\n\n  private _tChannelImplToWire(names: '*' | string[], arg: any, path: string, context: ValidatorContext): any {\n    if (arg instanceof Dispatcher)  {\n      if (names !== '*' && !names.includes(arg._type))\n        throw new ValidationError(`${path}: dispatcher with guid ${arg._guid} has type ${arg._type}, expected ${names.toString()}`);\n      return { guid: arg._guid };\n    }\n    throw new ValidationError(`${path}: expected dispatcher ${names.toString()}`);\n  }\n\n  existingDispatcher<DispatcherType>(object: any): DispatcherType | undefined {\n    return this._dispatcherByObject.get(object) as DispatcherType | undefined;\n  }\n","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/dispatchers/dispatcher.ts#L232-L268","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: sending a Page where a Frame is required\nawait connection.send('frame', 'click', { frame: page });\n\n// after: pass the correct type\nawait connection.send('frame', 'click', { frame: page.mainFrame() });","handlingStrategy":"type-guard","validationCode":"// Validate handle type before sending.\nfunction assertChannel(handle: { _type?: string }, expected: string[]) {\n  if (!handle || !expected.includes(handle._type!))\n    throw new Error(`Expected ${expected.join('|')}, got ${handle?._type}`);\n}","typeGuard":"function isChannelOf<T extends { _type: string }>(h: any, types: readonly string[]): h is T {\n  return !!h && typeof h._type === 'string' && types.includes(h._type);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["protocol","validation","type-mismatch","guid"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}