{"record":{"id":"6584d7939dae603e","repo":"apify/crawlee","slug":"stagehand-instance-not-found-for-browser","errorCode":null,"errorMessage":"Stagehand instance not found for browser","messagePattern":"Stagehand instance not found for browser","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/stagehand-crawler/src/internals/stagehand-controller.ts","lineNumber":39,"sourceCode":" * @ignore\n */\nexport class StagehandController extends BrowserController<BrowserType, LaunchOptions, PlaywrightBrowser> {\n    #stagehand: Stagehand | null = null;\n    readonly #stagehandInstances: WeakMap<PlaywrightBrowser, Stagehand>;\n\n    constructor(browserPlugin: StagehandPlugin, stagehandInstances: WeakMap<PlaywrightBrowser, Stagehand>) {\n        super(browserPlugin);\n        this.#stagehandInstances = stagehandInstances;\n    }\n\n    /**\n     * Gets the Stagehand instance associated with this controller's browser.\n     */\n    getStagehand(): Stagehand {\n        if (!this.#stagehand) {\n            this.#stagehand = this.#stagehandInstances.get(this.browser)!;\n            if (!this.#stagehand) {\n                throw new Error('Stagehand instance not found for browser');\n            }\n        }\n        return this.#stagehand;\n    }\n\n    /**\n     * Creates a new page using the browser's default context.\n     * We use Playwright's browser API directly since we connected via CDP.\n     */\n    protected override async _newPage(_contextOptions?: unknown): Promise<Page> {\n        try {\n            // Get the default context from the Playwright browser (connected via CDP)\n            const contexts = this.browser.contexts();\n            if (contexts.length === 0) {\n                throw new Error('No browser context available');\n            }\n\n            const context = contexts[0];","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/stagehand-crawler/src/internals/stagehand-controller.ts#L21-L57","documentation":"StagehandController.getStagehand() lazily resolves the Stagehand instance for this controller's browser from a shared #stagehandInstances WeakMap and caches it. The error means the map has no entry for this controller's browser — i.e. the Stagehand instance was never registered for that browser object.","triggerScenarios":"Calling controller.getStagehand() (or stagehand-crawler's setUpStagehand → getStagehand) when the browser was NOT launched through StagehandPlugin._launch, the browser instance was recreated after the map entry was set (WeakMap keyed by old browser object), or a user-supplied browser pool/generator bypasses the plugin's launch path.","commonSituations":"Mixing a plain Playwright browser pool with StagehandCrawler, reconfiguring the pool mid-run so a new browser replaces the original, or constructing a StagehandController manually without running the plugin.","solutions":["Use StagehandPlugin (stagehandPlugin() helper) in the browser pool configuration so _launch registers the instance","Keep the same browser object for the crawl's lifetime; avoid swapping/reconnecting the pool after init","Verify you are using StagehandCrawler with its own browser pool defaults rather than a generic BrowserPool","Add the instance manually only as a last resort: controller/'plugin' #stagehandInstances.set(browser, stagehand)"],"exampleFix":"// before\nconst crawler = new StagehandCrawler({\n    browserPoolOptions: { useFingerprints: false }, // plugin missing\n});\n// after\nimport { StagehandPlugin } from '@crawlee/stagehand-crawler';\nconst crawler = new StagehandCrawler({\n    browserPoolOptions: {\n        browserPlugins: [new StagehandPlugin()],\n    },\n});","handlingStrategy":"validation","validationCode":"const stagehandPlugin = new StagehandPlugin();\nif (!browserPoolOptions.browserPlugins?.some((p) => p instanceof StagehandPlugin)) {\n    throw new Error('StagehandCrawler requires StagehandPlugin in browserPoolOptions.browserPlugins');\n}","typeGuard":"function hasStagehand(controller) {\n    return typeof controller?.getStagehand === 'function' && controller.getStagehand() != null;\n}","tryCatchPattern":"try {\n    const stagehand = controller.getStagehand();\n} catch (err) {\n    if (err.message.includes('Stagehand instance not found')) {\n        throw new Error('Browser pool is not using StagehandPlugin; reconfigure browserPlugins');\n    }\n    throw err;\n}","preventionTips":["Always configure the pool with StagehandPlugin when using StagehandCrawler","Do not replace or reconnect browser instances after plugin launch","Keep one crawler/pool instance per Stagehand setup","Log the pool's plugin list at startup to catch misconfiguration early"],"tags":["stagehand","browser-pool","configuration"],"backgroundTag":"stagehand-instance-not-found","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}