BabylonJS/Babylon.js · error · Error
${context}: Unsupported mode ${primitive.mode}
Error message
${context}: Unsupported mode ${primitive.mode} What it means
KHR_draco_mesh_compression only supports triangle-based primitive modes (TRIANGLES=4 and TRIANGLE_STRIP=5). _loadVertexDataAsync throws this when the primitive's mode is any other value (points, lines, etc.), because the Draco decoder produces triangle geometry only.
Source
Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.ts:69
this._loader = loader;
this.enabled = DracoDecoder.DefaultAvailable && this._loader.isExtensionUsed(NAME);
}
/** @internal */
public dispose(): void {
delete this.dracoDecoder;
(this._loader as any) = null;
}
/**
* @internal
*/
// eslint-disable-next-line no-restricted-syntax
public _loadVertexDataAsync(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>> {
return GLTFLoader.LoadExtensionAsync<IKHRDracoMeshCompression, Geometry>(context, primitive, this.name, async (extensionContext, extension) => {
if (primitive.mode != undefined) {
if (primitive.mode !== MeshPrimitiveMode.TRIANGLES && primitive.mode !== MeshPrimitiveMode.TRIANGLE_STRIP) {
throw new Error(`${context}: Unsupported mode ${primitive.mode}`);
}
}
const attributes: { [kind: string]: number } = {};
const normalized: { [kind: string]: boolean } = {};
const loadAttribute = (name: string, kind: string) => {
const uniqueId = extension.attributes[name];
if (uniqueId == undefined) {
return;
}
babylonMesh._delayInfo = babylonMesh._delayInfo || [];
if (babylonMesh._delayInfo.indexOf(kind) === -1) {
babylonMesh._delayInfo.push(kind);
}
attributes[kind] = uniqueId;
View on GitHub (pinned to 0592b347b8)
Solutions
- Convert the primitive to TRIANGLES (or TRIANGLE_STRIP) in the asset, or remove Draco compression from non-triangle primitives
- Re-export with the DCC tool configured to not compress non-triangle primitives
- Split line/point geometry into separate non-Draco primitives/meshes
- Use glTF-Validator to flag mode/extension incompatibilities before loading
Example fix
// before
"primitives": [{ "mode": 1, "extensions": { "KHR_draco_mesh_compression": {...} } }]
// after
"primitives": [{ "mode": 4, "extensions": { "KHR_draco_mesh_compression": {...} } }] Defensive patterns
Strategy: validation
Validate before calling
for (const mesh of asset.meshes ?? []) {
for (const prim of mesh.primitives) {
if (prim.extensions?.KHR_draco_mesh_compression && ![4, 5].includes(prim.mode ?? 4)) {
throw new Error(`Draco primitive with unsupported mode ${prim.mode}`);
}
}
} Type guard
function isTriangleMode(mode: number | undefined): boolean {
return mode === undefined || mode === 4 || mode === 5;
} Try / catch
try {
await BABYLON.SceneLoader.LoadAsync('./', 'model.glb', engine);
} catch (e) {
if (e instanceof Error && e.message.includes('Unsupported mode')) {
console.error('Draco primitive uses non-triangle mode; fix asset or drop Draco');
} else throw e;
} Prevention
- Only apply Draco compression to TRIANGLES/TRIANGLE_STRIP primitives
- Configure exporters not to compress line/point geometry
- Run glTF-Validator in CI to catch mode/extension conflicts
When it happens
Trigger: Loading a glTF primitive with mode 0 (POINTS), 1 (LINES), 2 (LINE_LOOP), 3 (LINE_STRIP), or 6 (TRIANGLE_FAN) that also uses KHR_draco_mesh_compression.
Common situations: Exporters that Draco-compress all primitives regardless of mode; hand-toggled extensions on line/point primitives; assets combining wireframe/line geometry with Draco compression.
Related errors
- ${context}: ${error.message}
- ${extensionContext}: Invalid area light type (${light.type})
- ${context}: Irradiance coefficients are missing
- ${extensionContext}/attributes: Instance buffer accessors do
- ${extensionContext}: Pointer is missing
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/05b0d41d3b64dc78.
Report an issue: GitHub.