BabylonJS/Babylon.js · error · Error

Draco: Cannot decode invalid data type ${dataType}

Error message

Draco: Cannot decode invalid data type ${dataType}

What it means

When copying an attribute out of Draco's WASM heap, processAttribute looks up the attribute's data type in a table covering DT_INT8, DT_UINT8/16/32, DT_INT16, DT_INT32, DT_FLOAT32 and DT_FLOAT64. If the Draco attribute reports a data type not in this table (or dataType is undefined), it throws this Error since no typed array constructor or heap view exists for it.

Source

Thrown at packages/dev/core/src/Meshes/Compression/dracoCompressionWorker.ts:261

            const dataType = attribute.data_type();
            const numComponents = attribute.num_components();
            const normalized = attribute.normalized();
            const byteStride = attribute.byte_stride();
            const byteOffset = attribute.byte_offset();

            const dataTypeInfo: Record<number, { typedArrayConstructor: TypedArrayConstructor; heap: TypedArray }> = {
                [decoderModule.DT_FLOAT32]: { typedArrayConstructor: Float32Array, heap: decoderModule.HEAPF32 },
                [decoderModule.DT_INT8]: { typedArrayConstructor: Int8Array, heap: decoderModule.HEAP8 },
                [decoderModule.DT_INT16]: { typedArrayConstructor: Int16Array, heap: decoderModule.HEAP16 },
                [decoderModule.DT_INT32]: { typedArrayConstructor: Int32Array, heap: decoderModule.HEAP32 },
                [decoderModule.DT_UINT8]: { typedArrayConstructor: Uint8Array, heap: decoderModule.HEAPU8 },
                [decoderModule.DT_UINT16]: { typedArrayConstructor: Uint16Array, heap: decoderModule.HEAPU16 },
                [decoderModule.DT_UINT32]: { typedArrayConstructor: Uint32Array, heap: decoderModule.HEAPU32 },
            };

            const info = dataTypeInfo[dataType];
            if (!info) {
                throw new Error(`Draco: Cannot decode invalid data type ${dataType}`);
            }

            const numValues = numPoints * numComponents;
            const byteLength = numValues * info.typedArrayConstructor.BYTES_PER_ELEMENT;

            const ptr = decoderModule._malloc(byteLength);
            try {
                decoder.GetAttributeDataArrayForAllPoints(geometry, attribute, dataType, byteLength, ptr);
                const data = new info.typedArrayConstructor(info.heap.buffer, ptr, numValues);
                onAttributeData(kind, data.slice(), numComponents, byteOffset, byteStride, normalized);
            } finally {
                decoderModule._free(ptr);
            }
        };

        if (attributeIDs) {
            for (const kind in attributeIDs) {
                const id = attributeIDs[kind];

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Re-encode the asset restricting attributes to standard types (FLOAT32 positions, UINT8/16/32 indices, etc.).
  2. Upgrade/downgrade the draco_decoder module so its DT_* enum matches the encoder's types.
  3. Extend the dataTypeInfo table locally if you control the worker and need the extra type.
  4. Skip unsupported attributes instead of failing the whole decode if they are optional.

Example fix

// before
const info = dataTypeInfo[dataType]; // e.g. DT_BOOL (newer Draco) -> undefined -> throws

// after
const info = dataTypeInfo[dataType];
if (!info) {
  console.warn('Skipping attribute with unsupported type ' + dataType);
  return; // skip instead of throwing
}
Defensive patterns

Strategy: type-guard

Validate before calling

const SUPPORTED = new Set([1, 3, 5, 2, 4, 6]); // DT_INT8..DT_FLOAT64 as used by the worker
if (!SUPPORTED.has(dataType)) {
  throw new Error('attribute uses unsupported Draco data type: ' + dataType);
}

Type guard

const isSupportedDracoDataType = (t: number | undefined): t is number =>
  typeof t === 'number' && t >= 1 && t <= 6; // DT_INT8(1)..DT_FLOAT64(6)

Try / catch

try {
  geometry = await DecodeMesh(buffer);
} catch (e) {
  if (String(e?.message).includes('invalid data type')) {
    console.warn('Falling back: attribute data type unsupported by decoder');
    return decodeWithRawDracoModule(buffer); // or request re-encoded asset
  }
  throw e;
}

Prevention

When it happens

Trigger: An attribute in the decoded Draco geometry uses a data type outside the supported set — e.g. data encoded with a newer Draco version introducing new DT_* types, or attributes whose data type cannot be resolved (dataType undefined).

Common situations: Assets produced by newer/older Draco encoders than the bundled decoder; hand-authored Draco files with exotic attribute types; custom attributes (generics) using types Babylon's worker does not map.

Related errors


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