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

  1. Inspect `error.cause` to find the root Stagehand/LLM error
  2. Verify the model provider API key and quota in the Stagehand config
  3. Ensure the page is still open and stable before calling observe()
  4. Align the stagehand package version used by the crawler with the installed playwright-core
  5. 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

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


AI-assisted analysis of apify/crawlee@dbe57fb09c (2026-08-30). Data as JSON: /api/errors/2971e8fb11d6e1da. Report an issue: GitHub.