puppeteer/puppeteer · error · Error

Cannot poll with non-positive interval

Error message

Cannot poll with non-positive interval

What it means

Thrown by Realm.waitForFunction() (and the page/frame wrappers) when the `polling` option is a negative number. Polling controls how often the function is re-evaluated; a negative interval is invalid. Note the guard uses `polling < 0`, so the string modes ('raf', 'mutation') and 0 are accepted, despite the message saying 'non-positive'.

Source

Thrown at packages/puppeteer-core/src/api/Realm.ts:168

    Func extends EvaluateFunc<Params> = EvaluateFunc<Params>,
  >(
    pageFunction: Func | string,
    options: {
      polling?: 'raf' | 'mutation' | number;
      timeout?: number;
      root?: ElementHandle<Node>;
      signal?: AbortSignal;
    } = {},
    ...args: Params
  ): Promise<HandleFor<Awaited<ReturnType<Func>>>> {
    const {
      polling = 'raf',
      timeout = this.timeoutSettings.timeout(),
      root,
      signal,
    } = options;
    if (typeof polling === 'number' && polling < 0) {
      throw new Error('Cannot poll with non-positive interval');
    }
    const waitTask = new WaitTask(
      this,
      {
        polling,
        root,
        timeout,
        signal,
      },
      pageFunction as unknown as
        ((...args: unknown[]) => Promise<Awaited<ReturnType<Func>>>) | string,
      ...args,
    );
    return await waitTask.result;
  }

  /** @internal */
  abstract adoptBackendNode(backendNodeId?: number): Promise<JSHandle<Node>>;

View on GitHub (pinned to d484e21c17)

Solutions

  1. Use a positive polling interval in milliseconds (e.g. `polling: 100`).
  2. Prefer the string modes `polling: 'raf'` or `polling: 'mutation'` for most waits.
  3. If the interval is computed, clamp it: `polling: Math.max(0, interval)`.

Example fix

// before
await page.waitForFunction(() => window.ready, { polling: -50 });
// after
await page.waitForFunction(() => window.ready, { polling: 100 });
Defensive patterns

Strategy: validation

Validate before calling

if (typeof polling === 'number' && polling < 0) {
  throw new Error('polling must be >= 0');
}
await page.waitForFunction(fn, { polling });

Type guard

function isValidPolling(p: 'raf' | 'mutation' | number): boolean {
  return typeof p === 'string' || (typeof p === 'number' && p >= 0);
}

Try / catch

try {
  await page.waitForFunction(fn, { polling });
} catch (e) {
  if (e instanceof Error && /non-positive interval/.test(e.message)) {
    await page.waitForFunction(fn, { polling: 'raf' });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `page.waitForFunction(fn, { polling: -100 })`, `page.waitForSelector(sel, { polling: -1 })`, or any negative numeric polling value. The default is 'raf' (requestAnimationFrame), which is unaffected.

Common situations: Passing a computed interval that went negative; reusing a `timeout` value as `polling` by mistake; porting code that used a signed delta for delay.

Related errors


AI-assisted analysis of puppeteer/puppeteer@d484e21c17 (2026-08-12). Data as JSON: /api/errors/7858a55dabe6b96a. Report an issue: GitHub.