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
- Run 'start-perf-trace' first and confirm it returns success before calling stop.
- Make the stop call idempotent in your script: only stop when start reported that tracing is running.
- 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
- Pair start/stop calls in try/finally so stop only runs after a successful start.
- Track collector state in your script instead of calling stop unconditionally.
- Remember start may have failed (e.g. no scene) — check its return message.
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
- Performance instrumentation is not running. Run start-perf-i
- WebGPUDurationMeasure: index out of range (" + index + ")
- Freezing active meshes was cancelled
- Unable to connect to the Inspector bridge on port ${port} af
- Session id must be a number.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/d3ed8c662337dee3.
Report an issue: GitHub.