{"record":{"id":"7c7d1d72fa423cbb","repo":"apify/crawlee","slug":"provided-browserplugin-is-not-one-of-the-plugins-u","errorCode":null,"errorMessage":"Provided browserPlugin is not one of the plugins used by BrowserPool.","messagePattern":"Provided browserPlugin is not one of the plugins used by BrowserPool\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/browser-pool/src/browser-pool.ts","lineNumber":473,"sourceCode":"     * properties are consumed — cookie and header injection remain the\n     * crawler's responsibility.\n     */\n    async newPage(options: BrowserPoolNewPageOptions<PageOptions, BrowserPlugins[number]> = {}): Promise<PageReturn> {\n        const {\n            id = nanoid(),\n            pageOptions,\n            browserPlugin = this.pickBrowserPlugin(),\n            session,\n            proxyUrl = session?.proxyInfo?.url,\n            ignoreTlsErrors = session?.proxyInfo?.ignoreTlsErrors,\n        } = options;\n\n        if (this.pages.has(id)) {\n            throw new Error(`Page with ID: ${id} already exists.`);\n        }\n\n        if (browserPlugin && !this.browserPlugins.includes(browserPlugin)) {\n            throw new Error('Provided browserPlugin is not one of the plugins used by BrowserPool.');\n        }\n\n        // Bind the limiter callback to the current async-hooks context. p-limit\n        // otherwise resumes queued callbacks in the previous task's\n        // AsyncLocalStorage context, leaking aborted cancelTasks across unrelated\n        // requests (https://github.com/apify/crawlee/issues/3670). Mirrors the\n        // fix p-limit landed upstream in v5 (sindresorhus/p-limit#71); v5 is an\n        // ESM-only rewrite, so we can't bump it in Crawlee v3.\n        // Besides the cancelTask leak, the wrapper also keeps the per-request *storage transaction*\n        // ALS-scoped: without it, a queued callback would resume in the previous request's async\n        // context and run request B's storage writes inside request A's transaction.\n        // TODO(crawlee@v4): bump p-limit to v5 and drop this AsyncResource.bind wrapper.\n        // Limiter is necessary - https://github.com/apify/crawlee/issues/1126\n        return this.#limiter(\n            AsyncResource.bind(async () => {\n                let browserController = this.pickBrowserWithFreeCapacity(browserPlugin, { proxyUrl });\n\n                if (!browserController)","sourceCodeStart":455,"sourceCodeEnd":491,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/browser-pool/src/browser-pool.ts#L455-L491","documentation":"newPage() accepts an optional browserPlugin to select which plugin serves the page. Since the pool only knows the plugins it was constructed with, it throws this plain Error when the supplied plugin is not one of the pool's registered browserPlugins (identity check via includes).","triggerScenarios":"pool.newPage({ browserPlugin: somePlugin }) where somePlugin was never passed to the BrowserPool constructor — e.g. a plugin created in another module, from a different package copy, or a plugin of a different family.","commonSituations":"Creating plugins in multiple places and mixing instances; duplicate package versions making the seemingly-same plugin a different instance; passing a plugin from one pool to a different pool.","solutions":["Pass one of the exact plugin instances given to the BrowserPool constructor (keep references handy).","Register the plugin in the pool's browserPlugins array before using it.","Check membership first: pool.browserPlugins.includes(plugin)."],"exampleFix":"// before\nconst plugin = new PlaywrightPlugin(); // different instance than pool's\nawait pool.newPage({ browserPlugin: plugin }); // throws\n// after\nconst plugin = pool.browserPlugins[0];\nawait pool.newPage({ browserPlugin: plugin });","handlingStrategy":"validation","validationCode":"if (!pool.browserPlugins.includes(plugin)) throw new Error('register this plugin in the pool first');\nawait pool.newPage({ browserPlugin: plugin });","typeGuard":"function isPoolPlugin(pool, plugin) { return pool.browserPlugins.includes(plugin); }","tryCatchPattern":null,"preventionTips":["Always pick plugins from pool.browserPlugins, not fresh instances","Register needed plugins at pool construction","Avoid duplicate package versions creating distinct plugin instances"],"tags":["configuration","plugins","browser-pool"],"backgroundTag":"unknown-plugin-instance","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}