microsoft/playwright · error
Must start tracing before stopping
Error message
Must start tracing before stopping
What it means
Tracing.stopChunk() throws when there is no active/recording state AND the requested mode is not 'discard'. A non-discard stopChunk (entries/archive export) requires that tracing was actually started and a chunk recorded; calling it on an idle tracer means there is nothing to export.
Solutions
- Only call stopChunk with an export path when you know tracing was started and a chunk is open.
- Use mode: 'discard' for the teardown path that must be safe when nothing was recorded.
- Guard the export call behind a flag you set in startChunk.
Example fix
// before
afterEach(async () => {
await context.tracing.stopChunk({ path: 'trace.zip' }); // throws if never started
});
// after
afterEach(async () => {
if (tracingStarted) {
await context.tracing.stopChunk({ path: 'trace.zip' });
} else {
await context.tracing.stopChunk({ mode: 'discard' }).catch(() => {});
}
}); Defensive patterns
Strategy: validation
Validate before calling
let tracingActive = false;
async function guardedStop(ctx, out) {
if (!tracingActive) {
return ctx.tracing.stopChunk({ mode: 'discard' }).catch(() => ({}));
}
tracingActive = false;
return ctx.tracing.stopChunk({ path: out });
} Try / catch
try { await context.tracing.stopChunk({ path: out }); }
catch (e) {
if (/Must start tracing before stopping/i.test(String(e.message))) return;
throw e;
} Prevention
- Only export when you know a chunk was started and is open.
- Use mode:'discard' for safe teardown that may run when nothing was recorded.
- Set/clear a flag around startChunk/stopChunk in your harness.
When it happens
Trigger: Calling context.tracing.stopChunk({ path: 'x.zip' }) (default mode 'archive') or mode 'entries' before tracing.start() / startChunk(); calling export after tracing has already stopped and cleared _state.
Common situations: A conditional afterEach that always tries to export a trace even when tracing was disabled for that test; orchestrating chunks without first starting; calling stopChunk twice (second has no state).
Related errors
- Must start tracing before starting a new chunk
- Must stop trace file before stopping tracing
- Cannot start a trace chunk while stopping
- Cannot start tracing while stopping
- Tracing has been already started
AI-assisted analysis of microsoft/playwright@f1d33b5029 (2026-09-21).
Data as JSON: /api/errors/e69ee66fc3048412.
Report an issue: GitHub.
Appendix: source
Thrown at packages/playwright-core/src/server/trace/recorder/tracing.ts:460
if (params.mode === 'entries')
return { entries: result.entries };
const artifact = new Artifact(this._context, result.zipFileName);
artifact.reportFinished();
return { artifact };
} finally {
// Always release the recording state, even when saving the chunk failed.
this._isStopping = false;
if (this._state)
this._state.recording = false;
}
}
private _stopChunk(params: TracingTracingStopChunkParams, coverageFile: string | undefined): { entries: NameValue[], zipFileName: string } | undefined {
if (!this._state || !this._state.recording) {
if (params.mode !== 'discard')
throw new Error(`Must start tracing before stopping`);
return undefined;
}
this._closeAllGroups();
this._context.instrumentation.removeListener(this);
eventsHelper.removeEventListeners(this._eventListeners);
if (this._state.options.screencast)
this._stopScreencast();
// We don't need websocket frames outside of the recording window. This also
// stops updating websocket content blobs, which we want to stay unchanged for zipping.
this._harTracer.setOmitWebSocketFrames(true);
if (this._state.options.snapshotDom)
this._snapshotter?.stop();
this.flushHarEntries();
// Network file survives across chunks, make a snapshot before returning the resulting entries.View on GitHub (pinned to f1d33b5029)