{"record":{"id":"465e9ec6d3f237de","repo":"microsoft/playwright","slug":"function-name-has-been-already-registered-in","errorCode":null,"errorMessage":"Function \"${name}\" has been already registered in one of the pages","messagePattern":"Function \"(.+?)\" has been already registered in one of the pages","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/browserContext.ts","lineNumber":382,"sourceCode":"\n      this.bindingsInitScript = PageBinding.createInitScript(this);\n      this.initScripts.push(this.bindingsInitScript);\n      await this.doAddInitScript(this.bindingsInitScript);\n      await this.safeNonStallingEvaluateInAllFrames(this.bindingsInitScript.source, 'main');\n    })();\n    return await this._playwrightBindingExposed;\n  }\n\n  needsPlaywrightBinding(): boolean {\n    return this._playwrightBindingExposed !== undefined;\n  }\n\n  async exposeBinding(progress: Progress, name: string, playwrightBinding: frames.FunctionWithSource, forClient?: unknown, noGlobal?: boolean): Promise<PageBinding> {\n    if (this._pageBindings.has(name))\n      throw new Error(`Function \"${name}\" has been already registered`);\n    for (const page of this.pages()) {\n      if (page.getBinding(name))\n        throw new Error(`Function \"${name}\" has been already registered in one of the pages`);\n    }\n    await progress.race(this.exposePlaywrightBindingIfNeeded());\n    const binding = new PageBinding(this, name, playwrightBinding, noGlobal);\n    binding.forClient = forClient;\n    this._pageBindings.set(name, binding);\n    try {\n      await progress.race(this.doAddInitScript(binding.initScript));\n      await progress.race(this.safeNonStallingEvaluateInAllFrames(binding.initScript.source, 'main'));\n      return binding;\n    } catch (error) {\n      this._pageBindings.delete(name);\n      throw error;\n    }\n  }\n\n  async removeExposedBinding(binding: PageBinding) {\n    if (this._pageBindings.get(binding.name) !== binding)\n      return;","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/browserContext.ts#L364-L400","documentation":"Same exposeBinding flow, second guard: even if the context doesn't have the name, if any already-created page has a page-level binding with the same name, Playwright rejects it to prevent shadowing.","triggerScenarios":"`page.exposeBinding('foo', ...)` followed by `context.exposeBinding('foo', ...)`; or any ordering where pages already exist with a colliding binding.","commonSituations":"Mixing page-level and context-level `exposeBinding`/`exposeFunction` with the same name; adding context bindings after pages were created; global setup registering context bindings after per-page setup ran.","solutions":["Use distinct names for page vs context bindings","Expose at context level before creating pages, or stick to one level","Dispose page-level bindings before promoting to context"],"exampleFix":"// before\nawait page.exposeBinding('cb', h);\nawait context.exposeBinding('cb', h); // throws\n\n// after\nawait page.exposeBinding('pageCb', h);\nawait context.exposeBinding('ctxCb', h);","handlingStrategy":"validation","validationCode":"const ctxNames = new Set<string>();\nconst pageNames = new Set<string>();\nasync function exposeCtx(ctx: BrowserContext, name: string, fn: Function) {\n  if (ctxNames.has(name) || pageNames.has(name))\n    throw new Error(`Binding '${name}' already registered (page or context).`);\n  ctxNames.add(name);\n  await ctx.exposeBinding(name, fn as any);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Don't mix page-level and context-level bindings with the same name","Expose context bindings before creating pages","Pick one level (page or context) and stay consistent"],"tags":["browser-context","expose-binding","pages","duplicate"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}