microsoft/playwright · error · Error

Cannot start a trace chunk while stopping

Error message

Cannot start a trace chunk while stopping

What it means

Tracing.startChunk() refuses to begin a new chunk while a previous stopChunk() is still tearing down (the _isStopping flag is set). Chunk teardown does async work (sealing network file, flushing HAR, snapshotter.stop), and starting a chunk mid-teardown would race those writes.

Source

Thrown at packages/playwright-core/src/server/trace/recorder/tracing.ts:200

    if (options.snapshotScreen)
      this._fs.mkdir(path.join(tracesDir, 'screenshots'));
    if (options.snapshotAria)
      this._fs.mkdir(path.join(tracesDir, 'aria'));
    this._fs.writeFile(this._state.networkFile, '');
    // Tracing is 10x bigger if we include scripts in every trace.
    if (options.snapshotDom)
      this._harTracer.start({ omitScripts: !options.live });
    this._started = true;
  }

  async startChunk(progress: Progress, options: { name?: string, title?: string } = {}): Promise<{ traceName: string }> {
    if (this._state && this._state.recording)
      await this.stopChunk(progress, { mode: 'discard' });

    if (!this._state)
      throw new Error('Must start tracing before starting a new chunk');
    if (this._isStopping)
      throw new Error('Cannot start a trace chunk while stopping');

    this._state.recording = true;
    this._state.callsInProgress.clear();

    // - Browser context network trace is shared across chunks as it contains resources
    // used to serve page snapshots, so make a copy with the new name.
    // - APIRequestContext network traces are chunk-specific, always start from scratch.
    const preserveNetworkResources = this._context instanceof BrowserContext;
    if (options.name && options.name !== this._state.traceName)
      this._changeTraceName(this._state, options.name, preserveNetworkResources);
    else
      this._allocateNewTraceFile(this._state);
    if (!preserveNetworkResources) {
      this._state.crossChunkFiles = new Set();
      this._fs.writeFile(this._state.networkFile, '');
    }

    this._fs.mkdir(path.dirname(this._state.traceFile));

View on GitHub (pinned to c8fc3bf8d3)

Solutions

  1. Fully await the previous stopChunk() promise before calling startChunk().
  2. Serialise chunk operations on a shared context — never call start/stopChunk in parallel.
  3. If using resetForReuse, await it before issuing new chunk commands.

Example fix

// before
context.tracing.stopChunk({ path: 'a.zip' }); // not awaited
await context.tracing.startChunk({ name: 'b' }); // _isStopping

// after
await context.tracing.stopChunk({ path: 'a.zip' });
await context.tracing.startChunk({ name: 'b' });
Defensive patterns

Strategy: validation

Validate before calling

// Serialise chunk operations; never start a chunk until the prior stop resolves.
let chain = Promise.resolve();
function serialChunk(ctx, fn) {
  const run = chain.then(() => fn(ctx.tracing));
  chain = run.catch(() => {});
  return run;
}

Try / catch

try { await context.tracing.startChunk(o); }
catch (e) {
  if (/while stopping/.test(String(e.message))) {
    await new Promise(r => setImmediate(r));
    await context.tracing.startChunk(o);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling startChunk immediately after stopChunk without awaiting the full teardown; concurrent startChunk from the runner and user code; chaining chunks in rapid succession with a shared context.

Common situations: Programmatic trace chunking that doesn't fully await stopChunk; a worker reuse path that discards a chunk then starts another in the same tick; two beforeAll/afterAll blocks racing the same context.

Related errors


AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12). Data as JSON: /api/errors/a5812891b29f257f. Report an issue: GitHub.