{"record":{"id":"3ec581f2be362f3e","repo":"mastra-ai/mastra","slug":"allocation-sampling-did-not-restart","errorCode":null,"errorMessage":"Allocation sampling did not restart.","messagePattern":"Allocation sampling did not restart\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"mastracode/sdk/src/process-memory-diagnostics.ts","lineNumber":630,"sourceCode":"      this.latestCapturePath = finalPath;\n      this.latestError = null;\n    } catch (error) {\n      this.artifactWriteFailed = true;\n      this.latestError = `Unable to persist allocation capture: ${errorMessage(error)}`;\n      throw new Error(this.latestError, { cause: error });\n    } finally {\n      if (!final && !this.stopRequested && this.state === 'active') {\n        try {\n          await this.startSampling();\n        } catch (error) {\n          this.latestError = `Unable to restart allocation sampling: ${errorMessage(error)}`;\n          this.state = 'error';\n        }\n      }\n    }\n\n    if (!final && !this.stopRequested && !this.samplingActive) {\n      throw new Error(this.latestError ?? 'Allocation sampling did not restart.');\n    }\n\n    return { path: finalPath, sequence, timestamp, reason };\n  }\n\n  private async restartSamplingAfterFailure(): Promise<void> {\n    try {\n      await this.startSampling();\n    } catch (error) {\n      this.latestError = `Unable to restart allocation sampling: ${errorMessage(error)}`;\n      this.state = 'error';\n    }\n  }\n\n  private recordError(prefix: string, error: unknown): void {\n    this.latestError = `${prefix}: ${errorMessage(error)}`;\n  }\n","sourceCodeStart":612,"sourceCodeEnd":648,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/mastracode/sdk/src/process-memory-diagnostics.ts#L612-L648","documentation":"For non-final captures, captureEpoch() restarts allocation sampling in its finally block so the next epoch can be recorded. If sampling is still not active afterwards (startSampling threw and the failure was swallowed into latestError / state 'error'), the library throws 'Allocation sampling did not restart.' (or the recorded latestError). The capture itself succeeded, but the continuous sampling loop is broken.","triggerScenarios":"After a successful profile write, startSampling() (HeapProfiler.startSampling) fails in the finally block — inspector session degraded or closed — leaving samplingActive false; also reachable when state is not 'active' so the finally skips restart entirely.","commonSituations":"Inspector session dying mid-run (external debugger interference, worker teardown); HeapProfiler domain errors after heavy load; capture() racing with stop() so stopRequested/state prevents restart; Node inspector instability on very long-running processes.","solutions":["Check getStatus(): if state is 'error', stop() and start() a fresh diagnostics session — the current sampling loop cannot resume.","Read latestError for the 'Unable to restart allocation sampling: ...' message recorded by the finally block; fix the underlying inspector issue.","Verify no external debugger (DevTools, --inspect client) is contending for the session; use a dedicated inspector port.","If captures are triggered while stopRequested is set, stop mixing manual capture() with stop(); finalize with stop() instead.","Consider lowering capture frequency or upgrading Node if the inspector repeatedly fails under load."],"exampleFix":"// before\nawait diagnostics.capture('manual'); // throws: sampling did not restart\n// keep using same instance\n// after\ntry {\n  await diagnostics.capture('manual');\n} catch {\n  const s = await diagnostics.getStatus();\n  if (s.state === 'error') {\n    await diagnostics.stop();\n    await diagnostics.start();\n  }\n}","handlingStrategy":"fallback","validationCode":"const s = diagnostics.getStatus();\nif (s.state !== 'active') throw new Error('Diagnostics not active; start a fresh session before capturing.');","typeGuard":null,"tryCatchPattern":"try {\n  await diagnostics.capture('manual');\n} catch (e) {\n  if ((e as Error).message.includes('Allocation sampling did not restart')) {\n    // profile was saved, but the sampling loop is broken: recycle the session\n    await diagnostics.stop();\n    diagnostics = createDiagnostics(config);\n    await diagnostics.start();\n  } else throw e;\n}","preventionTips":["Treat any capture error as a signal to check state/latestError and recycle the session if not 'active'.","Don't interleave manual capture() calls with stop(); let stop() perform the final capture.","Keep the inspector session exclusive to diagnostics (dedicated --inspect port).","Periodically verify sampling continues: check that new allocation-*.heapprofile files appear at the capture interval."],"tags":["inspector","heap-profiler","state-error","restart"],"backgroundTag":"profiler-restart-failed","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}