{"record":{"id":"6ee399bd8740c5ce","repo":"microsoft/playwright","slug":"must-start-tracing-before-starting-a-new-chunk","errorCode":null,"errorMessage":"Must start tracing before starting a new chunk","messagePattern":"Must start tracing before starting a new chunk","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/trace/recorder/tracing.ts","lineNumber":198,"sourceCode":"    if (options.screencast)\n      this._fs.mkdir(path.join(tracesDir, 'screencast'));\n    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    }","sourceCodeStart":180,"sourceCodeEnd":216,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/trace/recorder/tracing.ts#L180-L216","documentation":"Tracing.startChunk() (which backs tracing.start() when used in two-step mode) requires that Tracing.start() has already allocated the trace state. The chunk model is: start() sets up the trace files once, then startChunk()/stopChunk() carve out recorded segments. Calling startChunk with no _state means the outer trace was never opened.","triggerScenarios":"Calling context.tracing.startChunk(...) before context.tracing.start(...); calling startChunk after a tracing.stop() that cleared _state; using the low-level chunk API directly without the preceding start.","commonSituations":"Custom tracing orchestration that skips the start step; a test harness that calls stop() between tests but forgets to re-start before the next chunk; partial teardown leaving _state undefined.","solutions":["Call context.tracing.start(...) once before any startChunk/stopChunk cycle.","Re-check the lifecycle: start() -> startChunk() -> ... -> stopChunk() -> stop().","If using trace: 'on'/'retain-on-failure' in the runner, let the runner manage start() and only call startChunk/stopChunk in after hooks."],"exampleFix":"// before\nawait context.tracing.startChunk({ name: 'login' }); // no _state\n\n// after\nawait context.tracing.start({ snapshots: true });\nawait context.tracing.startChunk({ name: 'login' });","handlingStrategy":"validation","validationCode":"// Ensure start() precedes startChunk().\nlet started = false;\nasync function beginChunk(ctx, opts, chunkOpts) {\n  if (!started) { await ctx.tracing.start(opts); started = true; }\n  return ctx.tracing.startChunk(chunkOpts);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat start() as a mandatory prerequisite of startChunk().","After stop() (which clears _state), call start() again before any chunk.","Prefer the one-shot tracing API unless you need multiple chunks."],"tags":["tracing","state-machine","lifecycle"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}