{"record":{"id":"e606e62b8d073716","repo":"vercel-labs/agent-browser","slug":"renders-recording-not-active-run-react-renders","errorCode":null,"errorMessage":"renders recording not active - run `react renders start` first","messagePattern":"renders recording not active - run `react renders start` first","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/native/react/scripts.rs","lineNumber":390,"sourceCode":"            const ch = getChanges(fiber);\n            for (const c of ch) {\n              if (data[name].changes.length < 50) data[name].changes.push(c);\n            }\n          }\n        }\n      }\n    }\n    walkFiber(fiber.child);\n    walkFiber(fiber.sibling);\n  }\n})()\n\"#;\n\n/// Stop script for fiber profiler. Returns the collected profile as JSON.\npub const RENDERS_STOP: &str = r#\"\n(() => {\n  const active = window.__AB_RENDERS_ACTIVE__;\n  if (!active) throw new Error(\"renders recording not active - run `react renders start` first\");\n\n  const data = window.__AB_RENDERS__;\n  const startTime = window.__AB_RENDERS_START__;\n  const elapsed = performance.now() - startTime;\n\n  const fpsData = window.__AB_RENDERS_FPS__;\n  let fpsStats = { avg: 0, min: 0, max: 0, drops: 0 };\n  if (fpsData) {\n    cancelAnimationFrame(fpsData.rafId);\n    if (fpsData.frames.length > 0) {\n      const fpsSamples = fpsData.frames.map((dt) => (dt > 0 ? 1000 / dt : 0));\n      const sum = fpsSamples.reduce((a, b) => a + b, 0);\n      fpsStats = {\n        avg: Math.round(sum / fpsSamples.length),\n        min: Math.round(Math.min(...fpsSamples)),\n        max: Math.round(Math.max(...fpsSamples)),\n        drops: fpsSamples.filter((f) => f < 30).length,\n      };","sourceCodeStart":372,"sourceCodeEnd":408,"githubUrl":"https://github.com/vercel-labs/agent-browser/blob/548b159b30eef119ccf6846c8bc807d0eaa3f6f8/cli/src/native/react/scripts.rs#L372-L408","documentation":"RENDERS_STOP reads window.__AB_RENDERS_ACTIVE__, which only 'react renders start' sets on that document (and which stop itself deletes). The error means no recording is live: either start was never called, or the page navigated/reloaded since start and the window globals were wiped.","triggerScenarios":"Running 'react renders stop' before any 'react renders start'; navigating (or the app triggering a full reload) between start and stop; calling stop twice — the second call fails because the first already deleted the flag.","commonSituations":"Agent workflows that assume recording persists across navigation; SPA full-page redirects; retrying a stop after a timeout when the first stop actually succeeded.","solutions":["Run 'agent-browser react renders start' first, exercise the page, then 'react renders stop'","If the page reloaded mid-recording, re-run start on the new document and reproduce the interaction again","Guard double-stop flows by checking the flag (see validation) or tracking state in your own code"],"exampleFix":"# before\nagent-browser react renders stop   # not active\n\n# after\nagent-browser react renders start\n# ... interact with the page ...\nagent-browser react renders stop","handlingStrategy":"validation","validationCode":"agent-browser eval \"window.__AB_RENDERS_ACTIVE__ === true\"\n# run before 'react renders stop'","typeGuard":"function rendersActive(win: Window): boolean {\n  return (win as any).__AB_RENDERS_ACTIVE__ === true;\n}","tryCatchPattern":null,"preventionTips":["Always pair start/stop in the same automation block","Track 'started' state in your own code so you never double-stop","Avoid full page navigations while a renders recording is live — they wipe the recording globals"],"tags":["react","profiling","state","cli"],"backgroundTag":null,"analyzedSha":"548b159b30eef119ccf6846c8bc807d0eaa3f6f8","analyzedAt":"2026-08-16T10:12:14.925Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}