apify/crawlee · error
Stagehand observe() failed: ${improveErrorMessage(error)}
Error message
Stagehand observe() failed: ${improveErrorMessage(error)} What it means
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.
Source
Thrown at packages/stagehand-crawler/src/internals/utils/stagehand-utils.ts:107
return await stagehand.extract(instruction, schema, { ...options, page: page as ExtractOptions['page'] });
} catch (error) {
throw new Error(`Stagehand extract() failed: ${improveErrorMessage(error)}`, {
cause: error,
});
}
};
/**
* Observe the page and get AI-suggested actions.
* Passes this specific page to Stagehand so it operates on the correct page.
*/
enhancedPage.observe = async (options?: Omit<ObserveOptions, 'page'>) => {
try {
// Pass the page option to ensure Stagehand operates on this specific page
// Cast needed because Stagehand types reference older playwright-core versions
return await stagehand.observe({ ...options, page: page as ObserveOptions['page'] });
} catch (error) {
throw new Error(`Stagehand observe() failed: ${improveErrorMessage(error)}`, {
cause: error,
});
}
};
/**
* Create an autonomous agent for multi-step workflows.
* Note: Agent operates on the page context.
*
* The `as any` cast is needed because stagehand.agent() has two overloaded signatures
* (streaming vs non-streaming) that TypeScript struggles to reconcile when assigning
* to a property.
*/
(enhancedPage as any).agent = (config?: AgentConfig) => {
try {
if (config?.stream === true) {
return stagehand.agent(config as AgentConfig & { stream: true });
}View on GitHub (pinned to dbe57fb09c)
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
Example fix
// before: unguarded observe that crashes the crawl
const results = await enhancedPage.observe({ instruction: 'find product links' });
// after: catch and inspect cause
try {
const results = await enhancedPage.observe({ instruction: 'find product links' });
} catch (err) {
log.error('observe failed', { cause: err.cause });
} Defensive patterns
Strategy: try-catch
Validate before calling
// ensure page is open and config has a model
if (page.isClosed?.()) throw new Error('Cannot observe a closed page');
if (!process.env.OPENAI_API_KEY && !config.modelApiKey) throw new Error('Missing model API key'); Type guard
function isEnhancedStagehandPage(p: unknown): p is EnhancedPage {
return typeof p === 'object' && p !== null && typeof (p as any).observe === 'function';
} Try / catch
try {
const results = await enhancedPage.observe({ instruction });
} catch (err) {
log.error('Stagehand observe failed', { cause: (err as Error).cause });
results = [];
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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).
Related errors
- Stagehand act() failed: ${improveErrorMessage(error)}
- Stagehand extract() failed: ${improveErrorMessage(error)}
- Stagehand agent() failed: ${improveErrorMessage(error)}
- Stagehand instance not found for browser
- No browser context available
AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30).
Data as JSON: /api/errors/2971e8fb11d6e1da.
Report an issue: GitHub.