{"record":{"id":"a5812891b29f257f","repo":"microsoft/playwright","slug":"cannot-start-a-trace-chunk-while-stopping","errorCode":null,"errorMessage":"Cannot start a trace chunk while stopping","messagePattern":"Cannot start a trace chunk while stopping","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/trace/recorder/tracing.ts","lineNumber":200,"sourceCode":"    if (options.snapshotScreen)\n      this._fs.mkdir(path.join(tracesDir, 'screenshots'));\n    if (options.snapshotAria)\n      this._fs.mkdir(path.join(tracesDir, 'aria'));\n    this._fs.writeFile(this._state.networkFile, '');\n    // Tracing is 10x bigger if we include scripts in every trace.\n    if (options.snapshotDom)\n      this._harTracer.start({ omitScripts: !options.live });\n    this._started = true;\n  }\n\n  async startChunk(progress: Progress, options: { name?: string, title?: string } = {}): Promise<{ traceName: string }> {\n    if (this._state && this._state.recording)\n      await this.stopChunk(progress, { mode: 'discard' });\n\n    if (!this._state)\n      throw new Error('Must start tracing before starting a new chunk');\n    if (this._isStopping)\n      throw new Error('Cannot start a trace chunk while stopping');\n\n    this._state.recording = true;\n    this._state.callsInProgress.clear();\n\n    // - Browser context network trace is shared across chunks as it contains resources\n    // used to serve page snapshots, so make a copy with the new name.\n    // - APIRequestContext network traces are chunk-specific, always start from scratch.\n    const preserveNetworkResources = this._context instanceof BrowserContext;\n    if (options.name && options.name !== this._state.traceName)\n      this._changeTraceName(this._state, options.name, preserveNetworkResources);\n    else\n      this._allocateNewTraceFile(this._state);\n    if (!preserveNetworkResources) {\n      this._state.crossChunkFiles = new Set();\n      this._fs.writeFile(this._state.networkFile, '');\n    }\n\n    this._fs.mkdir(path.dirname(this._state.traceFile));","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/trace/recorder/tracing.ts#L182-L218","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Fully await the previous stopChunk() promise before calling startChunk().","Serialise chunk operations on a shared context — never call start/stopChunk in parallel.","If using resetForReuse, await it before issuing new chunk commands."],"exampleFix":"// before\ncontext.tracing.stopChunk({ path: 'a.zip' }); // not awaited\nawait context.tracing.startChunk({ name: 'b' }); // _isStopping\n\n// after\nawait context.tracing.stopChunk({ path: 'a.zip' });\nawait context.tracing.startChunk({ name: 'b' });","handlingStrategy":"validation","validationCode":"// Serialise chunk operations; never start a chunk until the prior stop resolves.\nlet chain = Promise.resolve();\nfunction serialChunk(ctx, fn) {\n  const run = chain.then(() => fn(ctx.tracing));\n  chain = run.catch(() => {});\n  return run;\n}","typeGuard":null,"tryCatchPattern":"try { await context.tracing.startChunk(o); }\ncatch (e) {\n  if (/while stopping/.test(String(e.message))) {\n    await new Promise(r => setImmediate(r));\n    await context.tracing.startChunk(o);\n  } else throw e;\n}","preventionTips":["Fully await each stopChunk before the next startChunk.","Don't issue chunk commands from parallel hooks on the same context.","Await resetForReuse before new chunk commands."],"tags":["tracing","state-machine","concurrency","await"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}