microsoft/playwright · error · Error
Recording is in progress, stop it before showing the…
Error message
Recording is in progress, stop it before showing the recorder.
What it means
RecorderApp.show opens the interactive codegen inspector for a context. If any ProgrammaticRecorderApp is already recording on that context (tracked in the programmaticRecorderApps set), showing the inspector would conflict with the API-driven recording, so it throws. Stop the programmatic recording first.
Solutions
- Stop the in-progress programmatic recording (stopRecording) before calling showRecorder.
- Use a separate browser context for the interactive recorder.
- Gate the showRecorder call on your app's recording state.
Example fix
// before
await context.startRecording({ language: 'python' });
await context.showRecorder({ mode: 'inspecting' });
// after
await context.startRecording({ language: 'python' });
await context.stopRecording();
await context.showRecorder({ mode: 'inspecting' }); Defensive patterns
Strategy: try-catch
Try / catch
try {
await context.showRecorder({ mode: 'inspecting' });
} catch (e) {
if (e.message.includes('Recording is in progress')) {
await context.stopRecording();
await context.showRecorder({ mode: 'inspecting' });
} else throw e;
} Prevention
- Serialize recorder operations per context with a simple mutex/queue.
- Never mix interactive codegen and programmatic recording on the same context.
When it happens
Trigger: Calling the BrowserContext.showRecorder channel method (or RecorderApp.show directly) while a recording started via startRecording / ProgrammaticRecorderApp.start is active on the same context.
Common situations: A tool starts an API recording for test generation and the user simultaneously opens the interactive codegen UI on the same context; automation scripts that show the recorder before stopping an earlier recording.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Recorder is shown, close it before starting a recording.
- Recording is already in progress.
- Failed to parse response
- Recording is already in progress.
AI-assisted analysis of microsoft/playwright@500c9c822c (2026-09-15).
Data as JSON: /api/errors/a563ef24883d1c24.
Report an issue: GitHub.
Appendix: source
Thrown at packages/playwright-core/src/server/recorder/recorderApp.ts:185
highlightRequested: async (params: { selector?: string; ariaTemplate?: AriaTemplateNode }) => {
if (params.selector)
await this._recorder.setHighlightedSelector(params.selector);
if (params.ariaTemplate)
await this._recorder.setHighlightedAriaTemplate(params.ariaTemplate);
},
};
await this._page.exposeBinding(progress, 'sendCommand', async (_, data: any) => {
const { method, params } = data as { method: string; params: any };
return await (dispatcher as any)[method].call(dispatcher, params);
});
}
static async show(context: BrowserContext, params: channels.BrowserContextShowRecorderParams) {
if (process.env.PW_CODEGEN_NO_INSPECTOR)
return;
if (programmaticRecorderApps(context).size)
throw new Error('Recording is in progress, stop it before showing the recorder.');
const recorder = await Recorder.forContext(context, params);
if (!(context as any)[recorderAppSymbol])
(context as any)[recorderAppSymbol] = await RecorderApp._show(recorder, context, params);
if (params.mode)
await recorder.setMode(params.mode);
}
async close() {
await this._page.close(nullProgress);
}
private static async _show(recorder: Recorder, inspectedContext: BrowserContext, params: channels.BrowserContextShowRecorderParams): Promise<RecorderApp> {
const sdkLanguage = inspectedContext._browser.sdkLanguage();
const isChromium = inspectedContext._browser.options.browserType === 'chromium';
const headed = !!inspectedContext._browser.options.headful;
const { createPlaywright } = require('../playwright') as typeof import('../playwright');
const recorderPlaywright = createPlaywright({ sdkLanguage: 'javascript', isInternalPlaywright: true });
const { context: appContext, page } = await launchApp(recorderPlaywright.chromium, {View on GitHub (pinned to 500c9c822c)