apify/crawlee · error

Stagehand extract() failed: ${improveErrorMessage(error)}

Error message

Stagehand extract() failed: ${improveErrorMessage(error)}

What it means

enhancePageWithStagehand wraps Stagehand's extract() for structured data extraction on crawler pages. Any exception from stagehand.extract() (schema mismatch, LLM/API failure, page not ready, Stagehand internal error) is rethrown as 'Stagehand extract() failed: <improved message>' with the original error preserved as cause.

Source

Thrown at packages/stagehand-crawler/src/internals/utils/stagehand-utils.ts:91

            });
        }
    };

    /**
     * Extract structured data from the page using natural language and a Zod schema.
     * Passes this specific page to Stagehand so it operates on the correct page.
     */
    enhancedPage.extract = async <T>(
        instruction: string,
        schema: ZodType<T>,
        options?: Omit<ExtractOptions, 'page'>,
    ): Promise<T> => {
        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.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,
            });

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Inspect the improved message / err.cause; fix auth (API key env vars) or model configuration if it's an LLM error
  2. Loosen or correct the Zod schema (make optional fields optional) so extraction can succeed on real page content
  3. Ensure the page is loaded and stable before extract() (wait for selector / networkidle)
  4. Add retry with backoff for transient LLM/rate-limit failures
  5. Verify network access to the LLM provider from the crawl environment

Example fix

// before
const data = await page.extract({ instruction: 'get the price', schema: z.object({ price: z.number() }) });
// after
try {
    const data = await page.extract({
        instruction: 'Extract the product price from the page',
        schema: z.object({ price: z.string().optional() }),
    });
} catch (err) {
    log.warning('extract failed', err.cause ?? err);
}
Defensive patterns

Strategy: try-catch

Validate before calling

function canExtract(page, schema) {
    return !page.isClosed?.() && typeof schema?.safeParse === 'function'
        && !!(process.env.OPENAI_API_KEY || process.env.ANTHROPIC_API_KEY);
}

Type guard

const isExtractFailure = (e) => e instanceof Error && e.message.startsWith('Stagehand extract() failed:');

Try / catch

try {
    const data = await page.extract({ instruction, schema });
} catch (err) {
    if (isExtractFailure(err)) {
        log.warning('extract failed', err.cause ?? err);
        return fallbackValue; // continue crawl without this record
    }
    throw err;
}

Prevention

When it happens

Trigger: Calling page.extract({ instruction, schema }) when the LLM call fails (missing/invalid API key, rate limits, timeouts), the schema cannot be satisfied by the page content, the page navigated or closed mid-extraction, or Stagehand's internal page mapping is stale.

Common situations: Zod schema fields the page cannot fill, missing OPENAI_API_KEY or wrong model name, extracting from pages that redirect immediately, and corporate proxies blocking the LLM API endpoint.

Related errors


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