BabylonJS/Babylon.js · error · Error
Draco: Missing position attribute for encoding.
Error message
Draco: Missing position attribute for encoding.
What it means
EncodeMesh in the Draco encoder worker requires at least one attribute whose Draco name is 'POSITION' because Draco meshes are defined by their point positions. Before encoding it searches the supplied attribute list and throws this Error if none is found.
Source
Thrown at packages/dev/core/src/Meshes/Compression/dracoCompressionWorker.ts:51
* @internal
*/
export function EncodeMesh(
module: unknown /** EncoderModule */,
attributes: Array<IDracoAttributeData>,
indices: Nullable<Uint16Array | Uint32Array>,
options: IDracoEncoderOptions
): IDracoEncodedMeshData {
const encoderModule = module as EncoderModule;
let encoder: Nullable<Encoder> = null;
let meshBuilder: Nullable<MeshBuilder> = null;
let mesh: Nullable<Mesh> = null;
let encodedNativeBuffer: Nullable<DracoInt8Array> = null;
const attributeIDs: Record<string, number> = {}; // Babylon kind -> Draco unique id
// Double-check that at least a position attribute is provided
const positionAttribute = attributes.find((a) => a.dracoName === "POSITION");
if (!positionAttribute) {
throw new Error("Draco: Missing position attribute for encoding.");
}
// If no indices are provided, assume mesh is unindexed. Let's generate them, since Draco meshes require them.
// TODO: This may be the POINT_CLOUD case, but need to investigate. Should work for now-- just less efficient.
if (!indices) {
// Assume position attribute is the largest attribute.
const positionVerticesCount = positionAttribute.data.length / positionAttribute.size;
indices = new (positionVerticesCount > 65535 ? Uint32Array : Uint16Array)(positionVerticesCount);
for (let i = 0; i < positionVerticesCount; i++) {
indices[i] = i;
}
}
try {
encoder = new encoderModule.Encoder();
meshBuilder = new encoderModule.MeshBuilder();
mesh = new encoderModule.Mesh();
View on GitHub (pinned to 0592b347b8)
Solutions
- Include the position attribute in the attributes array with dracoName 'POSITION' (kind: VertexBuffer.PositionKind).
- Verify each attribute's dracoName/kind mapping before calling encodeMesh.
- If the source mesh truly has no positions, Draco encoding is inapplicable — store the data another way.
Example fix
// before
const attributes = [{ kind: VertexBuffer.NormalKind, dracoName: 'NORMAL', data: normals }];
// after
const attributes = [
{ kind: VertexBuffer.PositionKind, dracoName: 'POSITION', data: positions },
{ kind: VertexBuffer.NormalKind, dracoName: 'NORMAL', data: normals }
]; Defensive patterns
Strategy: validation
Validate before calling
const hasPosition = attributes.some((a) => a.dracoName === 'POSITION');
if (!hasPosition) {
throw new Error('encodeMesh requires a position attribute (dracoName: POSITION)');
} Type guard
const hasPositionAttribute = (attrs: { dracoName: string }[]): attrs is [{ dracoName: 'POSITION' }, ...typeof attrs] =>
attrs.some((a) => a.dracoName === 'POSITION'); Try / catch
try {
const result = await encodeMeshAsync(attributes, indices, options);
} catch (e) {
if (String(e?.message).includes('Missing position attribute')) {
attributes = [POSITION_ATTR, ...attributes];
return encodeMeshAsync(attributes, indices, options);
}
throw e;
} Prevention
- Always build attribute lists starting with VertexBuffer.PositionKind / dracoName 'POSITION'.
- Write a unit test asserting every encoded mesh includes a POSITION attribute.
- When extracting attributes from a mesh programmatically, never filter out the position buffer.
When it happens
Trigger: Calling DracoEncoder encodeMesh (or the high-level _encodeAsync path) with an attributes array that lacks a VertexBuffer.PositionKind entry — e.g. encoding normals/UVs only, or passing a kind string other than 'position'.
Common situations: Compressing point clouds/mesh metadata without positions; building the attribute list programmatically and skipping the position buffer; passing attribute descriptors with wrong dracoName values.
Related errors
- Draco: Failed to encode.
- Draco: Cannot decode invalid geometry type ${type}
- Draco: Cannot exclude position attribute from encoding.
- Draco: Cannot encode geometry with no vertices.
- The mesh must at least have positions and indices
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/04661c86943689c9.
Report an issue: GitHub.