{"record":{"id":"f5116d08a46c54e2","repo":"microsoft/playwright","slug":"path-no-object-with-guid-guid","errorCode":null,"errorMessage":"${path}: no object with guid ${guid}","messagePattern":"(.+?): no object with guid (.+?)","errorType":"validation","errorClass":"ValidationError","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/dispatchers/dispatcher.ts","lineNumber":248,"sourceCode":"      binary: this._isInProcess ? 'buffer' : 'toBase64',\n      isUnderTest,\n    };\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;","sourceCodeStart":230,"sourceCodeEnd":266,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/dispatchers/dispatcher.ts#L230-L266","documentation":"ValidationError raised in DispatcherConnection._tChannelImplFromWire when an inbound message references a guid that is not present in _dispatcherByGuid. Every channel argument must resolve to a live server-side Dispatcher; a missing guid means the handle is unknown here — typically because the object was already disposed (context/page closed), was never created on this connection, or the guid was fabricated.","triggerScenarios":"Sending any RPC that takes a channel handle (page, frame, elementHandle, request, response, JSHandle, etc.) whose guid is no longer registered: reusing a handle after its browser/context closed; sending a guid from a different connection; passing a guid string that was made up or truncated.","commonSituations":"Use-after-close: holding a Page/ElementHandle across an await during which the context is torn down, then calling a method on it; multi-connection code mixing handles from one connection into another; long-running scripts that cache handles past the object's lifetime.","solutions":["Do not reuse handles after their owner is closed; close contexts/browser explicitly and drop references.","Keep handles scoped to the connection that created them and never pass a guid across connections.","After closing a context/browser, null out cached handles so accidental reuse fails locally rather than at the server.","If you build protocol messages by hand, validate that every guid you send came from a prior result on the same connection."],"exampleFix":"// before: reuse page after context close\nconst page = await context.newPage();\nawait context.close();\nawait page.click('#x'); // guid unknown -> ValidationError\n\n// after: drop references on close\nconst page = await context.newPage();\nawait context.close();\n// page is now invalid; do not call methods on it","handlingStrategy":"validation","validationCode":"// Track live handles per connection and check before reuse.\nconst live = new WeakSet<object>();\nfunction track<T extends object>(h: T): T { live.add(h); return h; }\nfunction isLive(h: object): boolean { return live.has(h); }\n// after context/browser close, callers should stop using tracked handles","typeGuard":"function isLiveHandle<T extends { _guid?: string }>(h: T | null | undefined, registry: Set<string>): h is T {\n  return !!h && typeof h._guid === 'string' && registry.has(h._guid);\n}","tryCatchPattern":"try {\n  await page.click('#x');\n} catch (e) {\n  if (/no object with guid/.test(e.message)) { /* handle was disposed; recreate or end session */ }\n  else throw e;\n}","preventionTips":["Never use a handle after its context/browser is closed; null references on close.","Keep handles on the connection that created them; never pass guids across connections.","Avoid caching handles across long awaits where close can intervene.","When building protocol messages by hand, validate each guid against current live handles."],"tags":["protocol","validation","guid","lifecycle","use-after-close"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}