{"record":{"id":"469975f598bdc20d","repo":"microsoft/playwright","slug":"no-recording-in-progress-use-startrecording-sch","errorCode":null,"errorMessage":"No recording in progress, use ${startRecording.schema.name} to start one.","messagePattern":"No recording in progress, use (.+?) to start one\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/tools/backend/recorder.ts","lineNumber":54,"sourceCode":"    response.addTextResult(`Recording started. Call ${stopRecording.schema.name} to retrieve the recorded actions.`);\n  },\n});\n\nconst stopRecording = defineTool({\n  capability: 'devtools',\n\n  schema: {\n    name: 'browser_stop_recording',\n    title: 'Stop recording user actions',\n    description: 'Stop the recording started with browser_start_recording and return the recorded actions as Playwright code.',\n    inputSchema: z.object({}),\n    type: 'readOnly',\n  },\n\n  handle: async (context, params, response) => {\n    const recordedActions = await context.stopRecording();\n    if (!recordedActions)\n      throw new Error(`No recording in progress, use ${startRecording.schema.name} to start one.`);\n    if (!recordedActions.length) {\n      response.addTextResult('Recording stopped. No actions were recorded.');\n    } else {\n      const codeframe = codeframeForLanguage(context.codegenLanguage());\n      response.addTextResult(`Recording stopped. Recorded actions:\\n\\n\\`\\`\\`${codeframe}\\n${recordedActions.join('\\n')}\\n\\`\\`\\``);\n    }\n    response.setIncludeSnapshot();\n  },\n});\n\nexport default [\n  startRecording,\n  stopRecording,\n];\n","sourceCodeStart":36,"sourceCodeEnd":69,"githubUrl":"https://github.com/microsoft/playwright/blob/deda92d15e7d771aacaae47eb2b6e47a562c30ff/packages/playwright-core/src/tools/backend/recorder.ts#L36-L69","documentation":"Thrown by the stopRecording tool handler when context.stopRecording() returns falsy, meaning no recording session was ever started (or it was already stopped). It tells the caller to start a recording before trying to stop one.","triggerScenarios":"Invoking the stopRecording MCP tool before any successful startRecording call, or calling stopRecording twice (the second call returns undefined because _recordedActions was already cleared).","commonSituations":"An MCP agent assumes recording is on (e.g. a prior startRecording call failed on version skew) and proceeds to stop; client state desync after a reconnect; double-submit of the stop tool.","solutions":["Call startRecording first and confirm it succeeded before stopping","Track client-side whether a recording is active; don't call stop twice","If state is unknown, treat this error as a no-op signal that no recording exists"],"exampleFix":"// before\nawait client.callTool({ name: 'stopRecording', arguments: {} });\n\n// after\nawait client.callTool({ name: 'startRecording', arguments: {} });\n// ... record actions ...\nawait client.callTool({ name: 'stopRecording', arguments: {} });","handlingStrategy":"validation","validationCode":"// Track session state client-side before calling the tool\nif (!recordingActive) { console.log('no recording to stop'); } else {\n  await client.callTool({ name: 'stopRecording', arguments: {} });\n  recordingActive = false;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await client.callTool({ name: 'stopRecording', arguments: {} });\n} catch (e) {\n  if ((e as Error).message.includes('No recording in progress')) return; // treat as no-op\n  throw e;\n}","preventionTips":["Set a recordingActive flag after a successful startRecording and clear it on stop","Never call stopRecording twice without an intervening start","Handle the startRecording failure path so you don't later stop a nonexistent session"],"tags":["recording","mcp","state","tool-call"],"backgroundTag":"invalid-state-transition","analyzedSha":"deda92d15e7d771aacaae47eb2b6e47a562c30ff","analyzedAt":"2026-08-27T19:20:32.228Z","contentChangedAt":"2026-08-27T19:20:32.228Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}