{"record":{"id":"a563ef24883d1c24","repo":"microsoft/playwright","slug":"recording-is-in-progress-stop-it-before-showing-the-recorder","errorCode":null,"errorMessage":"Recording is in progress, stop it before showing the recorder.","messagePattern":"Recording is in progress, stop it before showing the recorder\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/recorder/recorderApp.ts","lineNumber":185,"sourceCode":"      highlightRequested: async (params: { selector?: string; ariaTemplate?: AriaTemplateNode }) => {\n        if (params.selector)\n          await this._recorder.setHighlightedSelector(params.selector);\n        if (params.ariaTemplate)\n          await this._recorder.setHighlightedAriaTemplate(params.ariaTemplate);\n      },\n    };\n\n    await this._page.exposeBinding(progress, 'sendCommand', async (_, data: any) => {\n      const { method, params } = data as { method: string; params: any };\n      return await (dispatcher as any)[method].call(dispatcher, params);\n    });\n  }\n\n  static async show(context: BrowserContext, params: channels.BrowserContextShowRecorderParams) {\n    if (process.env.PW_CODEGEN_NO_INSPECTOR)\n      return;\n    if (programmaticRecorderApps(context).size)\n      throw new Error('Recording is in progress, stop it before showing the recorder.');\n    const recorder = await Recorder.forContext(context, params);\n    if (!(context as any)[recorderAppSymbol])\n      (context as any)[recorderAppSymbol] = await RecorderApp._show(recorder, context, params);\n    if (params.mode)\n      await recorder.setMode(params.mode);\n  }\n\n  async close() {\n    await this._page.close(nullProgress);\n  }\n\n  private static async _show(recorder: Recorder, inspectedContext: BrowserContext, params: channels.BrowserContextShowRecorderParams): Promise<RecorderApp> {\n    const sdkLanguage = inspectedContext._browser.sdkLanguage();\n    const isChromium = inspectedContext._browser.options.browserType === 'chromium';\n    const headed = !!inspectedContext._browser.options.headful;\n    const { createPlaywright } = require('../playwright') as typeof import('../playwright');\n    const recorderPlaywright = createPlaywright({ sdkLanguage: 'javascript', isInternalPlaywright: true });\n    const { context: appContext, page } = await launchApp(recorderPlaywright.chromium, {","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/microsoft/playwright/blob/500c9c822ce7664539a4c8a88810048dfe090c3b/packages/playwright-core/src/server/recorder/recorderApp.ts#L167-L203","documentation":"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.","triggerScenarios":"Calling the BrowserContext.showRecorder channel method (or RecorderApp.show directly) while a recording started via startRecording / ProgrammaticRecorderApp.start is active on the same context.","commonSituations":"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.","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."],"exampleFix":"// before\nawait context.startRecording({ language: 'python' });\nawait context.showRecorder({ mode: 'inspecting' });\n// after\nawait context.startRecording({ language: 'python' });\nawait context.stopRecording();\nawait context.showRecorder({ mode: 'inspecting' });","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await context.showRecorder({ mode: 'inspecting' });\n} catch (e) {\n  if (e.message.includes('Recording is in progress')) {\n    await context.stopRecording();\n    await context.showRecorder({ mode: 'inspecting' });\n  } else throw e;\n}","preventionTips":["Serialize recorder operations per context with a simple mutex/queue.","Never mix interactive codegen and programmatic recording on the same context."],"tags":["recorder","codegen","state-conflict"],"backgroundTag":"invalid-state-transition","analyzedSha":"500c9c822ce7664539a4c8a88810048dfe090c3b","analyzedAt":"2026-09-15T07:37:15.003Z","contentChangedAt":"2026-09-15T07:37:15.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}