{"record":{"id":"2971e8fb11d6e1da","repo":"apify/crawlee","slug":"stagehand-observe-failed-improveerrormessage","errorCode":null,"errorMessage":"Stagehand observe() failed: ${improveErrorMessage(error)}","messagePattern":"Stagehand observe\\(\\) failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/stagehand-crawler/src/internals/utils/stagehand-utils.ts","lineNumber":107,"sourceCode":"            return await stagehand.extract(instruction, schema, { ...options, page: page as ExtractOptions['page'] });\n        } catch (error) {\n            throw new Error(`Stagehand extract() failed: ${improveErrorMessage(error)}`, {\n                cause: error,\n            });\n        }\n    };\n\n    /**\n     * Observe the page and get AI-suggested actions.\n     * Passes this specific page to Stagehand so it operates on the correct page.\n     */\n    enhancedPage.observe = async (options?: Omit<ObserveOptions, 'page'>) => {\n        try {\n            // Pass the page option to ensure Stagehand operates on this specific page\n            // Cast needed because Stagehand types reference older playwright-core versions\n            return await stagehand.observe({ ...options, page: page as ObserveOptions['page'] });\n        } catch (error) {\n            throw new Error(`Stagehand observe() failed: ${improveErrorMessage(error)}`, {\n                cause: error,\n            });\n        }\n    };\n\n    /**\n     * Create an autonomous agent for multi-step workflows.\n     * Note: Agent operates on the page context.\n     *\n     * The `as any` cast is needed because stagehand.agent() has two overloaded signatures\n     * (streaming vs non-streaming) that TypeScript struggles to reconcile when assigning\n     * to a property.\n     */\n    (enhancedPage as any).agent = (config?: AgentConfig) => {\n        try {\n            if (config?.stream === true) {\n                return stagehand.agent(config as AgentConfig & { stream: true });\n            }","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/apify/crawlee/blob/dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c/packages/stagehand-crawler/src/internals/utils/stagehand-utils.ts#L89-L125","documentation":"enhancePageWithStagehand wraps page.observe() so any error thrown by the underlying Stagehand SDK during an observe call is rethrown with a consistent 'Stagehand observe() failed:' prefix and the original error attached as cause via improveErrorMessage(). This exists so crawler code can distinguish Stagehand failures from Playwright errors. The original error is preserved in `cause` for diagnosis.","triggerScenarios":"Calling enhancedPage.observe() when the Stagehand SDK's observe() throws: invalid/ambiguous instruction, model API auth failure or quota exhaustion, LLM returning malformed output, page closed mid-observation, or browser/context already destroyed.","commonSituations":"Missing or invalid model API key (OPENAI/ANTHROPIC etc.), rate limiting after many observe calls, observing a page that navigated or closed, passing options the installed Stagehand version does not support (version drift between crawler and stagehand SDK).","solutions":["Inspect `error.cause` to find the root Stagehand/LLM error","Verify the model provider API key and quota in the Stagehand config","Ensure the page is still open and stable before calling observe()","Align the stagehand package version used by the crawler with the installed playwright-core","Wrap observe() in retry logic with backoff for transient LLM failures"],"exampleFix":"// before: unguarded observe that crashes the crawl\nconst results = await enhancedPage.observe({ instruction: 'find product links' });\n\n// after: catch and inspect cause\ntry {\n  const results = await enhancedPage.observe({ instruction: 'find product links' });\n} catch (err) {\n  log.error('observe failed', { cause: err.cause });\n}","handlingStrategy":"try-catch","validationCode":"// ensure page is open and config has a model\nif (page.isClosed?.()) throw new Error('Cannot observe a closed page');\nif (!process.env.OPENAI_API_KEY && !config.modelApiKey) throw new Error('Missing model API key');","typeGuard":"function isEnhancedStagehandPage(p: unknown): p is EnhancedPage {\n  return typeof p === 'object' && p !== null && typeof (p as any).observe === 'function';\n}","tryCatchPattern":"try {\n  const results = await enhancedPage.observe({ instruction });\n} catch (err) {\n  log.error('Stagehand observe failed', { cause: (err as Error).cause });\n  results = [];\n}","preventionTips":["Verify model provider API keys and quotas before crawling","Check page.isClosed() before observe/agent calls","Keep stagehand SDK and playwright-core versions aligned","Retry observe with backoff for transient LLM errors"],"tags":["stagehand","llm","browser-automation"],"backgroundTag":"stagehand-call-failed","analyzedSha":"dbe57fb09ca607ad59dcf998f3925ef9ac3bb26c","analyzedAt":"2026-08-30T22:22:28.328Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}