apify/crawlee · error

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

Error message

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

What it means

enhancePageWithStagehand wraps page.agent() so any synchronous error thrown while starting a Stagehand agent (e.g. invalid AgentConfig or SDK-level failure before streaming begins) is rethrown with a 'Stagehand agent() failed:' prefix and the original error as cause. Note it only covers the synchronous invocation; agent execution errors surface via the returned agent/promise.

Source

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

        }
    };

    /**
     * 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 });
            }
            return stagehand.agent(config as AgentConfig & { stream?: false });
        } catch (error) {
            throw new Error(`Stagehand agent() failed: ${improveErrorMessage(error)}`, {
                cause: error,
            });
        }
    };

    return enhancedPage;
}

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Inspect `error.cause` for the root SDK error
  2. Validate AgentConfig fields (model name, apiKey/env vars) before calling agent()
  3. Check the installed stagehand SDK supports the streaming option you pass
  4. Confirm the model provider credentials and account limits
  5. Update the stagehand package to match the crawler's expected API

Example fix

// before
const agent = enhancedPage.agent({ model: 'gpt-4o', stream: true });

// after
try {
  const agent = enhancedPage.agent({ model: 'gpt-4o', stream: true });
} catch (err) {
  log.error('agent failed to start', { cause: err.cause });
}
Defensive patterns

Strategy: try-catch

Validate before calling

function validateAgentConfig(cfg: unknown): asserts cfg is AgentConfig {
  if (typeof cfg !== 'object' || cfg === null) throw new TypeError('agent config must be an object');
  if (!('model' in cfg)) throw new TypeError('agent config requires a model');
}

Type guard

function isAgentConfig(v: unknown): v is AgentConfig {
  return typeof v === 'object' && v !== null && typeof (v as any).model === 'string';
}

Try / catch

try {
  const agent = enhancedPage.agent(config);
} catch (err) {
  log.error('Stagehand agent failed to start', { cause: (err as Error).cause });
}

Prevention

When it happens

Trigger: Calling enhancedPage.agent(config) where stagehand.agent() throws synchronously: malformed AgentConfig, unsupported stream option for the installed SDK version, model provider misconfiguration, or Stagehand instance already closed.

Common situations: Passing `stream: true` to a Stagehand version that lacks streaming agents, missing model API credentials, invalid model name in AgentConfig, constructing the agent on a closed Stagehand instance.

Related errors


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