BabylonJS/Babylon.js · error · Error

${context}: ${error.message}

Error message

${context}: ${error.message}

What it means

This wraps any error raised during Draco mesh decoding into `${context}: ${error.message}` while building the geometry via _decodeMeshToGeometryForGltfAsync. The original draco decoder failure (corrupt compressed data, missing attributes, decoder errors) is re-thrown with the glTF JSON path context prepended so the failing primitive can be identified.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.ts:119

            loadAttribute("TEXCOORD_2", VertexBuffer.UV3Kind);
            loadAttribute("TEXCOORD_3", VertexBuffer.UV4Kind);
            loadAttribute("TEXCOORD_4", VertexBuffer.UV5Kind);
            loadAttribute("TEXCOORD_5", VertexBuffer.UV6Kind);
            loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
            loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
            loadAttribute("COLOR_0", VertexBuffer.ColorKind);

            const bufferView = ArrayItem.Get(extensionContext, this._loader.gltf.bufferViews, extension.bufferView) as IBufferViewDraco;
            if (!bufferView._dracoBabylonGeometry) {
                bufferView._dracoBabylonGeometry = this._loader.loadBufferViewAsync(`/bufferViews/${bufferView.index}`, bufferView).then(async (data) => {
                    const dracoDecoder = this.dracoDecoder || DracoDecoder.Default;
                    const positionAccessor = ArrayItem.TryGet(this._loader.gltf.accessors, primitive.attributes["POSITION"]);
                    const babylonBoundingInfo =
                        !this._loader.parent.alwaysComputeBoundingBox && !babylonMesh.skeleton && positionAccessor ? LoadBoundingInfoFromPositionAccessor(positionAccessor) : null;
                    return await dracoDecoder
                        ._decodeMeshToGeometryForGltfAsync(babylonMesh.name, this._loader.babylonScene, data, attributes, normalized, babylonBoundingInfo)
                        .catch((error) => {
                            throw new Error(`${context}: ${error.message}`);
                        });
                });
            }

            return await bufferView._dracoBabylonGeometry;
        });
    }
}

let _Registered = false;
/**
 * Registers the KHR_draco_mesh_compression glTF loader extension.
 * Safe to call multiple times; only the first call has an effect.
 */
// eslint-disable-next-line @typescript-eslint/naming-convention
export function RegisterKHR_draco_mesh_compression(): void {
    if (_Registered) {
        return;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Re-export/re-compress the asset with a current Draco encoder and verify it loads in a reference viewer
  2. Ensure the GLB/buffer data is complete (re-upload; check byteLength)
  3. Confirm extension.attributes attribute ids match the encoded Draco data
  4. Check the underlying error.message in this wrapper for the true decoder cause and address it

Example fix

// before
bufferView._dracoBabylonGeometry = decode(corruptBuffer) // rejects
// after: re-export with gltf-transform + draco3d encoder, verify offline, then load
Defensive patterns

Strategy: try-catch

Validate before calling

const bv = gltf.bufferViews[ext.bufferView];
if (!bv || bv.byteLength === 0) throw new Error('Draco bufferView missing or empty');

Try / catch

try {
  await BABYLON.SceneLoader.LoadAsync('./', 'model.glb', engine);
} catch (e) {
  if (e instanceof Error && /\/meshes\/\d+\/primitives\/\d+/.test(e.message)) {
    console.error(`Draco decode failed for primitive: ${e.message}`);
    // fall back to loading a non-Draco variant of the asset
  } else throw e;
}

Prevention

When it happens

Trigger: A primitive with KHR_draco_mesh_compression whose compressed bufferView data is corrupt, truncated, or encoded with attributes that don't match the declared attributes/normalized map, causing the Draco decoder promise to reject.

Common situations: Truncated GLB uploads; assets compressed with an incompatible Draco encoder version; bufferView data modified/re-compressed incorrectly by post-processing tools; mismatch between extension.attributes ids and data inside the Draco buffer.

Related errors


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