BabylonJS/Babylon.js · error · Error

Draco: Cannot exclude position attribute from encoding.

Error message

Draco: Cannot exclude position attribute from encoding.

What it means

Draco encoding cannot represent a mesh without positions, so `PrepareAttributesForDraco` throws if the `excludedAttributes` option lists VertexBuffer.PositionKind. Every other attribute kind may be excluded, but the position attribute is mandatory for the encoder.

Source

Thrown at packages/dev/core/src/Meshes/Compression/dracoEncoder.ts:65

        indices = (AreIndices32Bits(indices, indices.length) ? Uint32Array : Uint16Array).from(indices);
    }

    return indices;
}

/**
 * Get relevant information about the geometry's vertex attributes for Draco encoding. Eventually used for each attribute as
 * `AddFloatAttribute(mesh: Mesh, attribute: number, count: number, itemSize: number, array: TypedArray)`
 * where `attribute = EncoderModule[<dracoAttribute>]`, `itemSize = <size>`, `array = <data>`, and count is the number of position vertices.
 * @internal
 */
function PrepareAttributesForDraco(input: Mesh | Geometry, excludedAttributes?: string[]): Array<IDracoAttributeData> {
    const attributes: Array<IDracoAttributeData> = [];

    for (const kind of input.getVerticesDataKinds()) {
        if (excludedAttributes?.includes(kind)) {
            if (kind === VertexBuffer.PositionKind) {
                throw new Error("Draco: Cannot exclude position attribute from encoding.");
            }
            continue;
        }

        // Convert number[] to typed array, if needed.
        const vertexBuffer = input.getVertexBuffer(kind)!;
        const size = vertexBuffer.getSize();
        const data = GetTypedArrayData(vertexBuffer.getData()!, size, vertexBuffer.type, vertexBuffer.byteOffset, vertexBuffer.byteStride, input.getTotalVertices(), true);
        attributes.push({ kind: kind, dracoName: GetDracoAttributeName(kind), size: size, data: data });
    }

    return attributes;
}

const DefaultEncoderOptions: IDracoEncoderOptions = {
    decodeSpeed: 5,
    encodeSpeed: 5,
    method: "MESH_EDGEBREAKER_ENCODING",

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Remove VertexBuffer.PositionKind ("position") from the excludedAttributes array.
  2. Filter exclusions programmatically: `excludedAttributes.filter(k => k !== VertexBuffer.PositionKind)`.
  3. If the mesh truly shouldn't encode positions, don't use Draco encoding for it.

Example fix

// before
await encoder.encodeMeshAsync(mesh, { excludedAttributes: [VertexBuffer.PositionKind, VertexBuffer.NormalKind] });

// after
await encoder.encodeMeshAsync(mesh, { excludedAttributes: [VertexBuffer.NormalKind] });
Defensive patterns

Strategy: validation

Validate before calling

const excluded = (opts.excludedAttributes ?? []).filter(k => k !== VertexBuffer.PositionKind);
await encoder.encodeMeshAsync(mesh, { ...opts, excludedAttributes: excluded });

Type guard

function exclusionsAreValid(excluded?: string[]): boolean {
    return !excluded?.includes(VertexBuffer.PositionKind);
}

Try / catch

try {
    return await encoder.encodeMeshAsync(mesh, options);
} catch (e) {
    if (e instanceof Error && e.message.includes("Cannot exclude position attribute")) {
        options.excludedAttributes = options.excludedAttributes?.filter(k => k !== VertexBuffer.PositionKind);
        return await encoder.encodeMeshAsync(mesh, options);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling `DracoEncoder.encodeMeshAsync(mesh, { excludedAttributes: [VertexBuffer.PositionKind] })`, or passing an exclusion list built dynamically (e.g. excluding all non-essential kinds) that happens to include "position".

Common situations: Trying to shrink files aggressively by excluding attributes; copying an exclusion list (like ["normal","uv","position"]) from another encoder config; or a generic "exclude all except index" pipeline that wrongly includes position.

Related errors


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