BabylonJS/Babylon.js · error

Performance trace is not running. Run start-perf-trace first

Error message

Performance trace is not running. Run start-perf-trace first.

What it means

Thrown by the 'stop-perf-trace' command when perfCollector is null or its isStarted flag is false, i.e. stop was called without a prior successful start. The command exists to stop collection and return datasets as JSON; without a running collector there is nothing to stop or report.

Source

Thrown at packages/dev/inspector-v2/src/services/cli/perfTraceCommandService.ts:47

                    return "Performance trace is already running.";
                }

                perfCollector = scene.getPerfCollector();
                perfCollector.stop();
                perfCollector.clear(false);
                perfCollector.addCollectionStrategies(...DefaultPerfStrategies);
                perfCollector.start(true);

                return "Performance trace started.";
            },
        });

        const stopReg = commandRegistry.addCommand({
            id: "stop-perf-trace",
            description: "Stop collecting performance trace data and return the results as JSON.",
            executeAsync: async () => {
                if (!perfCollector || !perfCollector.isStarted) {
                    throw new Error("Performance trace is not running. Run start-perf-trace first.");
                }

                perfCollector.stop();

                const datasets = perfCollector.datasets;
                const ids = datasets.ids;
                const rawData = datasets.data.subarray(0, datasets.data.itemLength);
                const sliceSize = ids.length + PerformanceViewerCollector.SliceDataOffset;

                const samples: Record<string, unknown>[] = [];
                for (let i = 0; i < rawData.length; i += sliceSize) {
                    const timestamp = rawData[i];
                    const sample: Record<string, unknown> = { timestamp };
                    for (let j = 0; j < ids.length; j++) {
                        sample[ids[j]] = rawData[i + PerformanceViewerCollector.SliceDataOffset + j];
                    }
                    samples.push(sample);
                }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Run 'start-perf-trace' first and confirm it returns success before calling stop.
  2. Make the stop call idempotent in your script: only stop when start reported that tracing is running.
  3. If start failed, fix the underlying cause (e.g. no active scene) rather than retrying stop.

Example fix

// before
await execute("stop-perf-trace", {}); // never started
// after
const res = await execute("start-perf-trace", {});
if (!res.includes("already running")) {
  const data = await execute("stop-perf-trace", {});
}
Defensive patterns

Strategy: validation

Validate before calling

if (!perfCollector?.isStarted) return; // nothing to stop; skip or start first

Type guard

function isTraceRunning(c: { isStarted: boolean } | null | undefined): boolean { return !!c && c.isStarted; }

Try / catch

try {
  await stopPerfTrace();
} catch (e) {
  if (e instanceof Error && e.message.startsWith("Performance trace is not running")) {
    // treat as no-op or start-then-stop
  } else throw e;
}

Prevention

When it happens

Trigger: Executing 'stop-perf-trace' before 'start-perf-trace'; after a previous stop already ran; or when start failed earlier (e.g. 'No active scene.') leaving perfCollector unset or not started.

Common situations: A scripted start/stop pair where the start step failed silently earlier; calling stop twice at the end of a profiling session; the collector auto-stopped on scene teardown and the user calls stop again.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/d3ed8c662337dee3. Report an issue: GitHub.