{"record":{"id":"59a316da651e1ed5","repo":"microsoft/playwright","slug":"must-stop-trace-file-before-stopping-tracing","errorCode":null,"errorMessage":"Must stop trace file before stopping tracing","messagePattern":"Must stop trace file before stopping tracing","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/trace/recorder/tracing.ts","lineNumber":336,"sourceCode":"    this._allocateNewTraceFile(state);\n\n    const newNetworkFile = path.join(state.tracesDir, name + '.network');\n    if (preserveNetworkResources)\n      this._fs.copyFile(state.networkFile, newNetworkFile);\n    state.networkFile = newNetworkFile;\n  }\n\n  async stop(progress: Progress) {\n    await progress.race(this._stop());\n  }\n\n  private async _stop() {\n    if (!this._state)\n      return;\n    if (this._isStopping)\n      throw new Error(`Tracing is already stopping`);\n    if (this._state.recording)\n      throw new Error(`Must stop trace file before stopping tracing`);\n    this._closeAllGroups();\n    this._harTracer.stop();\n    this.flushHarEntries();\n    await this._fs.syncAndGetError().finally(() => {\n      this._state = undefined;\n    });\n  }\n\n  async deleteTmpTracesDir() {\n    if (this._tracesTmpDir)\n      await removeFolders([this._tracesTmpDir]);\n  }\n\n  private _createTracesDirIfNeeded() {\n    if (this._precreatedTracesDir)\n      return this._precreatedTracesDir;\n    this._tracesTmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'playwright-tracing-'));\n    return this._tracesTmpDir;","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/trace/recorder/tracing.ts#L318-L354","documentation":"Tracing.stop() throws when a chunk is still recording (this._state.recording is true). The tracing lifecycle requires that you stop the current chunk (stopChunk) before stopping the whole trace; otherwise the open chunk's files and HAR entries would be left inconsistent.","triggerScenarios":"Calling context.tracing.stop() while a startChunk is active and no stopChunk has been issued; calling stop() right after start() without ever starting/stopping a chunk.","commonSituations":"Using tracing.start() (which under two-step usage needs a chunk) and then calling stop() directly; forgetting the stopChunk step; a custom trace loop that skips chunk teardown.","solutions":["Issue context.tracing.stopChunk(...) before context.tracing.stop().","If you only used tracing.start({ ... }) without manual chunks, use the one-shot API tracing.start + tracing.stop with a stopChunk in between, or rely on the runner.","Verify _state.recording is false (chunk closed) before calling stop()."],"exampleFix":"// before\nawait context.tracing.start({ snapshots: true });\nawait context.tracing.startChunk({ name: 'flow' });\nawait context.tracing.stop(); // recording still true\n\n// after\nawait context.tracing.start({ snapshots: true });\nawait context.tracing.startChunk({ name: 'flow' });\nawait context.tracing.stopChunk({ path: 'flow.zip' });\nawait context.tracing.stop();","handlingStrategy":"validation","validationCode":"// Always close the current chunk before stopping the trace.\nasync function finish(ctx, out) {\n  await ctx.tracing.stopChunk({ path: out }).catch(() => {});\n  await ctx.tracing.stop();\n}","typeGuard":null,"tryCatchPattern":"try { await context.tracing.stop(); }\ncatch (e) {\n  if (/Must stop trace file/i.test(String(e.message))) {\n    await context.tracing.stopChunk({ mode: 'discard' }).catch(() => {});\n    await context.tracing.stop();\n  } else throw e;\n}","preventionTips":["Follow the order: start -> startChunk -> stopChunk -> stop.","In afterEach, always stopChunk (even discard) before stop.","Don't call stop() while a chunk is recording."],"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"}