BabylonJS/Babylon.js · error
WebGPUDurationMeasure: index out of range (" + index + ")
Error message
WebGPUDurationMeasure: index out of range (" + index + ") What it means
WebGPUDurationMeasure (timestamp query helper) allocates a query set with a fixed count (this._count). startPass writes two timestamps at index+2 and index+3, so if index+3 exceeds the allocated count the writes would fall outside the query set. Babylon throws to prevent corrupting the GPU query set.
Source
Thrown at packages/dev/core/src/Engines/WebGPU/webgpuTimestampQuery.ts:131
constructor(engine: WebGPUEngine, device: GPUDevice, bufferManager: WebGPUBufferManager, count = 2, querySetLabel?: string) {
this._count = count;
this._querySet = new WebGPUQuerySet(engine, count, WebGPUConstants.QueryType.Timestamp, device, bufferManager, true, querySetLabel);
}
public start(encoder: GPUCommandEncoder): void {
(encoder as GPUCommandEncoderWithTimestamp).writeTimestamp?.(this._querySet.querySet, 0);
}
public async stop(encoder: GPUCommandEncoder): Promise<number | null> {
(encoder as GPUCommandEncoderWithTimestamp).writeTimestamp?.(this._querySet.querySet, 1);
return (encoder as GPUCommandEncoderWithTimestamp).writeTimestamp ? await this._querySet.readTwoValuesAndSubtract(0) : 0;
}
public startPass(descriptor: GPURenderPassDescriptor | GPUComputePassDescriptor, index: number): void {
if (index + 3 > this._count) {
throw new Error("WebGPUDurationMeasure: index out of range (" + index + ")");
}
descriptor.timestampWrites = {
querySet: this._querySet.querySet,
beginningOfPassWriteIndex: index + 2,
endOfPassWriteIndex: index + 3,
};
}
public async stopPass(index: number): Promise<number | null> {
return await this._querySet.readTwoValuesAndSubtract(index + 2);
}
public dispose() {
this._querySet.dispose();
}
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Initialize the duration measure with enough slots: call initTimeStampRegisters / create the measure with a count >= 2*(number of passes)+2
- Use distinct, incrementing indices per pass and verify the maximum index before calling
- Clamp or reuse measurement slots instead of allocating a new index per pass
Example fix
// before durationMeasure = new WebGPUDurationMeasure(engine, 4); durationMeasure.startPass(descriptor, 3); // 3+3 > 4 // after durationMeasure = new WebGPUDurationMeasure(engine, 8); // at least index+4 durationMeasure.startPass(descriptor, 3);
Defensive patterns
Strategy: validation
Validate before calling
const maxIndex = durationMeasure.getContainerSize?.() ?? count; // slots allocated
if (index + 4 > count) throw new RangeError(`Pass index ${index} exceeds allocated timestamp slots (${count})`); Type guard
function canStartPass(dm: { _count: number }, index: number): boolean {
return index + 3 < dm._count;
} Try / catch
try {
durationMeasure.startPass(descriptor, i);
} catch (e) {
if (e instanceof Error && e.message.startsWith('WebGPUDurationMeasure: index out of range')) {
console.warn(`Skipping timing for pass ${i}: not enough query slots`);
} else throw e;
} Prevention
- Allocate count >= 2 * passes + 2 when initializing the duration measure
- Keep a single counter for indices and assert its maximum before rendering
- Reuse timing slots rather than assigning a new index per pass
- Add a unit test covering startPass at the highest expected index
When it happens
Trigger: Passing an index too large to WebGPUDurationMeasure.startPass (or start/end pairs) such that index+3 >= count, e.g. measuring more passes than the duration measure was created for (initTimeStampRegisters/count).
Common situations: Performance instrumentation loops that call startPass/endPass for every draw pass but initialized the duration measure with too few registers; copy-pasted measurement code after increasing the number of passes.
Related errors
- Atmosphere is not supported on WebGL ${engine.version}.
- createComputeEffect: This engine does not support compute sh
- createComputePipelineContext: This engine does not support c
- computeDispatch: This engine does not support compute shader
- computeDispatchIndirect: This engine does not support comput
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/0c2fe6dcfa54ab3f.
Report an issue: GitHub.