apify/crawlee · error

AdaptivePlaywrightCrawler requires transactional storage - i

Error message

AdaptivePlaywrightCrawler requires transactional storage - it runs the request handler multiple times per request and must be able to discard the storage writes of losing attempts. `transactionalStorage: false` is therefore not supported; a write policy object is accepted and forwarded to the per-attempt transactions.

What it means

AdaptivePlaywrightCrawler may run the request handler up to twice per request (once with a static fetch, once with a browser) and uses transactional storage to discard writes made by the losing attempt. Disabling transactional storage (`transactionalStorage: false`) would make those writes un-discardable, so the constructor rejects it outright.

Source

Thrown at packages/playwright-crawler/src/internals/adaptive-playwright-crawler.ts:372

        // The extra fields are only tracked if the injected instance was built with them - the types enforce that,
        // but plain JS callers would otherwise silently increment `undefined` into a sticky `NaN`. Extend
        // `adaptivePlaywrightCrawlerStatisticState` to satisfy this.
        if (statistics !== undefined) {
            parseArgument(
                statistics.state,
                z.object({
                    httpOnlyRequestHandlerRuns: z.number(),
                    browserRequestHandlerRuns: z.number(),
                    renderingTypeMispredictions: z.number(),
                }),
                'statistics.state',
            );
        }

        // Per-attempt buffering is load-bearing here: the handler runs up to twice per request and the
        // losing attempt's writes must be discardable.
        if (transactionalStorage === false) {
            throw new Error(
                'AdaptivePlaywrightCrawler requires transactional storage - it runs the request handler ' +
                    'multiple times per request and must be able to discard the storage writes of losing ' +
                    'attempts. `transactionalStorage: false` is therefore not supported; a write policy ' +
                    'object is accepted and forwarded to the per-attempt transactions.',
            );
        }

        super({
            ...rest,
            errorHandler,
            failedRequestHandler,
            requestHandler,
            requestHandlerTimeoutSecs,
            // The base would build a `Statistics` without the adaptive fields, so provide a default that has them.
            // The cast covers a `StatisticStateExtension` that adds further fields - those can only come from an
            // injected instance, in which case this default is never built.
            statistics:
                statistics ??

View on GitHub (pinned to dbe57fb09c)

Solutions

  1. Remove `transactionalStorage: false` from the AdaptivePlaywrightCrawler options (the default is correct).
  2. If you need to tune write behavior, pass a write policy object instead of `false`; it is forwarded to the per-attempt transactions.
  3. If you truly cannot use transactional storage, switch to CheerioCrawler or PlaywrightCrawler, which do not retry handlers with alternative rendering.

Example fix

// before
const crawler = new AdaptivePlaywrightCrawler({ transactionalStorage: false });

// after
const crawler = new AdaptivePlaywrightCrawler({}); // default transactional storage required
Defensive patterns

Strategy: validation

Validate before calling

if (options.transactionalStorage === false) {
    throw new Error('AdaptivePlaywrightCrawler does not support transactionalStorage: false.');
}

Try / catch

let crawler;
try {
    crawler = new AdaptivePlaywrightCrawler(options);
} catch (err) {
    if (err.message.includes('transactional storage')) {
        delete options.transactionalStorage;
        crawler = new AdaptivePlaywrightCrawler(options);
    } else {
        throw err;
    }
}

Prevention

When it happens

Trigger: Constructing `new AdaptivePlaywrightCrawler({ transactionalStorage: false })`.

Common situations: Copying crawler options from PlaywrightCrawler/CheerioCrawler configurations where `transactionalStorage: false` is valid; disabling transactions to reduce storage overhead without realizing AdaptivePlaywrightCrawler depends on them.

Related errors


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