BabylonJS/Babylon.js · error
Vertex buffers pointing to the same buffer must have the sam
Error message
Vertex buffers pointing to the same buffer must have the same byte stride
What it means
When several vertex buffers share one underlying Buffer, the exporter must write the raw bytes once and describe each view with a byteStride. If the views referencing the same buffer declare different byteStrides, the single glTF bufferView layout would be ambiguous/incorrect, so the exporter throws instead of emitting a corrupted asset.
Source
Thrown at packages/dev/serializers/src/glTF/2.0/glTFExporter.ts:1038
}
const buffers = Array.from(bufferToVertexBuffersMap.keys());
for (const buffer of buffers) {
const data = buffer.getData();
if (!data) {
throw new Error("Buffer data is not available");
}
const vertexBuffers = bufferToVertexBuffersMap.get(buffer);
if (!vertexBuffers) {
continue;
}
const byteStride = vertexBuffers[0].byteStride;
if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {
throw new Error("Vertex buffers pointing to the same buffer must have the same byte stride");
}
const bytes = DataArrayToUint8Array(data).slice();
// Apply normalizations and color corrections to buffer data in-place.
for (const vertexBuffer of vertexBuffers) {
const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;
const { byteOffset, byteStride, componentCount, type, count, normalized, kind } = GetVertexBufferInfo(vertexBuffer, meshes);
switch (kind) {
// Normalize normals and tangents.
case VertexBuffer.NormalKind:
case VertexBuffer.TangentKind: {
EnumerateFloatValues(bytes, byteOffset, byteStride, componentCount, type, count, normalized, (values) => {
const length = Math.sqrt(values[0] * values[0] + values[1] * values[1] + values[2] * values[2]);
if (length > 0) {
const invLength = 1 / length;
values[0] *= invLength;
View on GitHub (pinned to 0592b347b8)
Solutions
- Make all vertex buffers sharing the same Buffer use the same byteStride value
- Split attributes with a different stride into their own separate Buffer instance so each buffer has a consistent stride
- Repack/rebuild the vertex data into a single consistent interleaved layout (or non-interleaved) before exporting
- Catch the error and export after normalizing the geometry
Example fix
// before new VertexBuffer(engine, data, VertexBuffer.PositionKind, true, 0, 20); // stride 20 new VertexBuffer(engine, data, VertexBuffer.NormalKind, true, 8, 16); // stride 16, same buffer // after new VertexBuffer(engine, data, VertexBuffer.PositionKind, true, 0, 20); new VertexBuffer(engine, data, VertexBuffer.NormalKind, true, 12, 20); // same stride 20 on same buffer
Defensive patterns
Strategy: validation
Validate before calling
function stridesConsistent(bufferToVertexBuffers: Map<IUnknown, IVertexBuffer[]>): boolean {
for (const [, vbs] of bufferToVertexBuffers) {
const s = vbs[0].byteStride;
if (vbs.some((vb) => vb.byteStride !== s)) return false;
}
return true;
} Try / catch
try {
await GLTF2Export.GLTFAsync(scene, "scene");
} catch (e) {
if (e instanceof Error && e.message.startsWith("Vertex buffers pointing to the same buffer")) {
// normalize strides and retry export
} else { throw e; }
} Prevention
- When building interleaved buffers, derive one shared STRIDE constant and use it for every attribute on that buffer
- Group attributes with different strides onto separate Buffer instances
- Add a unit test that asserts equal byteStride for all views sharing a buffer before export
- Review any custom setVerticesBuffer calls for hardcoded stride values
When it happens
Trigger: Registering multiple VertexBuffers that point to the same Buffer instance but were created with different byteStride values (e.g. interleaved position+uv with stride 20 plus a separately interleaved set with stride 16) and exporting them via GLTFExporter.
Common situations: Manual interleaved-vertex-buffer setups where some attributes were packed with different strides; merging meshes whose custom vertex layouts differ; a refactoring that changed stride for one attribute but not others sharing the buffer.
Related errors
- Unknown kind ${kind}
- Unknown kind: ${kind}
- Buffer data is not available
- Triangle strip/fan fill mode is not implemented
- Unknown fill mode: ${fillMode}
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/82ae4cfca03933b8.
Report an issue: GitHub.