mastra-ai/mastra · warning

GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records be

Error message

GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records before the next process sample.

What it means

Thrown during stop() when the in-memory pending GC event buffer overflowed (more than MAX_PENDING_GC_EVENTS=1000 events accumulated between process samples), meaning GC events were dropped and the gc-events.jsonl artifact is incomplete. stop() refuses to report a clean stop so the operator knows the GC log has gaps.

Source

Thrown at mastracode/sdk/src/process-memory-diagnostics.ts:441

    this.stopRequested = true;
    this.state = 'stopping';
    this.clearTimersAndObserver();

    if (startingPromise) {
      this.stoppingPromise = startingPromise.then(() => this.getStatus());
      return this.stoppingPromise;
    }

    this.stoppingPromise = (async () => {
      let stopError: string | null = null;
      try {
        if (this.outputDirectory) await this.takeSample();
        await this.enqueueCapture(async () => {
          if (this.inspector && this.samplingActive) await this.captureEpoch('stop', true);
        });
        await this.writeQueue;
        if (this.gcEventBufferOverflowed) {
          throw new Error(`GC event buffer exceeded ${MAX_PENDING_GC_EVENTS} records before the next process sample.`);
        }
        if (this.artifactWriteFailed) throw new Error('One or more process memory diagnostic artifact writes failed.');
        this.latestError = null;
      } catch (error) {
        stopError = `Unable to stop process memory diagnostics cleanly: ${errorMessage(error)}`;
        this.latestError = stopError;
      } finally {
        this.disconnectInspector();
        this.state = stopError ? 'error' : 'inactive';
      }
      return this.getStatus();
    })();

    return this.stoppingPromise;
  }

  private async createArtifacts(): Promise<void> {
    await mkdir(this.config.parentDirectory, { recursive: true, mode: 0o700 });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Lower MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS (closer to the 1000ms minimum) so pending GC events flush more often
  2. Increase heap headroom / reduce allocation churn so fewer GC events occur per interval
  3. Treat the run's gc-events.jsonl as partial; re-run the profiling session with a shorter sample interval

Example fix

// before
MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS=600000
// after
MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS=10000
Defensive patterns

Strategy: try-catch

Validate before calling

const status = diagnostics.getStatus();
if (status.gcEventCount > 900) console.warn('GC event count approaching buffer cap; consider shorter sample interval');

Try / catch

try {
  await diagnostics.stop();
} catch (error) {
  if (error.message.includes('GC event buffer exceeded')) {
    console.warn('GC events dropped; gc-events.jsonl is partial. Re-run with shorter sample interval.');
  } else throw error;
}

Prevention

When it happens

Trigger: Calling stop() when gcEventBufferOverflowed is true — i.e. the PerformanceObserver 'gc' callback filled pendingGcEvents to the 1000 cap before the periodic sample timer flushed them. Happens when sampling fails/stalls or the sample interval is long while the workload triggers very frequent GC.

Common situations: GC-heavy workloads (huge short-lived allocations) combined with a long MASTRACODE_PROFILE_SAMPLE_INTERVAL_MS, or timers not firing because the sample write queue is blocked.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/08f2216cebb55274. Report an issue: GitHub.