BabylonJS/Babylon.js · error

Unsupported attribute type: ${type}.

Error message

Unsupported attribute type: ${type}.

What it means

getNativeAttribType maps VertexBuffer component types (BYTE, UNSIGNED_BYTE, SHORT, UNSIGNED_SHORT, FLOAT) to native ATTRIB_TYPE_* enums. HALF_FLOAT, INT and UNSIGNED_INT deliberately have no native equivalent (the bindings only expose int8/uint8/int16/uint16/float), so any other type throws. This means those attribute types are unsupported on the Babylon Native engine by design.

Source

Thrown at packages/dev/core/src/Engines/Native/nativeHelpers.ts:371

}

export function getNativeAttribType(type: number): number {
    switch (type) {
        case VertexBuffer.BYTE:
            return _native.Engine.ATTRIB_TYPE_INT8;
        case VertexBuffer.UNSIGNED_BYTE:
            return _native.Engine.ATTRIB_TYPE_UINT8;
        case VertexBuffer.SHORT:
            return _native.Engine.ATTRIB_TYPE_INT16;
        case VertexBuffer.UNSIGNED_SHORT:
            return _native.Engine.ATTRIB_TYPE_UINT16;
        case VertexBuffer.FLOAT:
            return _native.Engine.ATTRIB_TYPE_FLOAT;
        // HALF_FLOAT (as well as INT and UNSIGNED_INT) has no equivalent in the native bindings, which only
        // expose ATTRIB_TYPE_INT8/UINT8/INT16/UINT16/FLOAT. Those vertex attribute types are therefore
        // WebGL/WebGPU only and intentionally fall through to the throw below on the Babylon Native engine.
        default:
            throw new Error(`Unsupported attribute type: ${type}.`);
    }
}

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Convert vertex data to Float32Array (or 8/16-bit types) before creating the VertexBuffer.
  2. Retarget the asset pipeline/glTF loader to avoid HALF_FLOAT accessors (normalize to float32).
  3. If 32-bit data is unavoidable, keep that mesh on the WebGL/WebGPU engine rather than NativeEngine.

Example fix

// before
new VertexBuffer(engine, halfFloatData, "position", false); // HALF_FLOAT
// after
new VertexBuffer(engine, new Float32Array(convertHalfToFloat(halfFloatData)), "position", false);
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED = new Set([BABYLON.VertexBuffer.BYTE, BABYLON.VertexBuffer.UNSIGNED_BYTE, BABYLON.VertexBuffer.SHORT, BABYLON.VertexBuffer.UNSIGNED_SHORT, BABYLON.VertexBuffer.FLOAT]);
if (!SUPPORTED.has(vertexData.type)) {
  vertexData = convertToFloat32(vertexData); // e.g. decode HALF_FLOAT to Float32Array
}

Type guard

function isNativeSupportedAttribType(type: number): boolean {
  const V = BABYLON.VertexBuffer;
  return [V.BYTE, V.UNSIGNED_BYTE, V.SHORT, V.UNSIGNED_SHORT, V.FLOAT].includes(type);
}

Try / catch

try {
  mesh.setVerticesBuffer(kind, buffer);
} catch (e) {
  if (String(e.message).startsWith('Unsupported attribute type')) {
    console.warn(`Converting ${kind} to FLOAT32 for NativeEngine`);
    mesh.setVerticesBuffer(kind, toFloat32Buffer(buffer));
  } else throw e;
}

Prevention

When it happens

Trigger: Creating a VertexBuffer with HALF_FLOAT, INT (0x1404 gl.INT) or UNSIGNED_INT (0x1405 gl.UNSIGNED_INT) data on a NativeEngine, e.g. float16 attribute data or 32-bit integer indices/attributes.

Common situations: Loading glTF models using half-float attributes; porting a WebGL/WebGPU scene that used INT attributes to Babylon Native; asset pipelines emitting f16 vertex data.

Related errors


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