BabylonJS/Babylon.js · error · Error
Draco: Failed to encode.
Error message
Draco: Failed to encode.
What it means
After building the Draco mesh and encoder, EncodeMesh calls encoder.EncodeMeshToDracoBuffer and checks the returned length. A non-positive length means the native Draco encoder produced no output (encoding failed internally), so the worker throws this Error instead of returning an empty buffer.
Source
Thrown at packages/dev/core/src/Meshes/Compression/dracoCompressionWorker.ts:111
attributeIDs[attribute.kind] = addAttribute(meshBuilder, mesh, encoderModule[attribute.dracoName], verticesCount, attribute.size, attribute.data);
if (options.quantizationBits && options.quantizationBits[attribute.dracoName]) {
encoder.SetAttributeQuantization(encoderModule[attribute.dracoName], options.quantizationBits[attribute.dracoName]);
}
}
// Set the options
if (options.method) {
encoder.SetEncodingMethod(encoderModule[options.method]);
}
if (options.encodeSpeed !== undefined && options.decodeSpeed !== undefined) {
encoder.SetSpeedOptions(options.encodeSpeed, options.decodeSpeed);
}
// Encode to native buffer
encodedNativeBuffer = new encoderModule.DracoInt8Array();
const encodedLength = encoder.EncodeMeshToDracoBuffer(mesh, encodedNativeBuffer);
if (encodedLength <= 0) {
throw new Error("Draco: Failed to encode.");
}
// Copy the native buffer data to worker heap
const encodedData = new Int8Array(encodedLength);
for (let i = 0; i < encodedLength; i++) {
encodedData[i] = encodedNativeBuffer.GetValue(i);
}
return { data: encodedData, attributeIds: attributeIDs };
} finally {
if (mesh) {
encoderModule.destroy(mesh);
}
if (meshBuilder) {
encoderModule.destroy(meshBuilder);
}
if (encoder) {
encoderModule.destroy(encoder);
View on GitHub (pinned to 0592b347b8)
Solutions
- Validate that every attribute's data length matches numPoints * numComponents and indices are within range before encoding.
- Simplify the options (e.g. drop quantization bits settings) to isolate which option breaks encoding.
- Check that the Draco encoder module version matches the data/features used (e.g. position quantization support).
- Log attribute sizes and index ranges and retry encoding after fixing the mesh data.
Example fix
// before
const mesh = { attributes, indices: badIndices }; // indices reference vertex 999999
encoder.EncodeMeshToDracoBuffer(mesh, out); // <= 0 -> throws
// after
const maxIndex = Math.max(...indices);
if (maxIndex >= positions.length / 3) {
indices = indices.filter((i) => i < positions.length / 3); // or fix mesh
}
const encodedLength = encoder.EncodeMeshToDracoBuffer(mesh, out); Defensive patterns
Strategy: validation
Validate before calling
const numPoints = positions.length / 3;
const maxIndex = indices.reduce((m, i) => Math.max(m, i), 0);
if (!Number.isFinite(numPoints) || numPoints === 0) throw new Error('empty position data');
if (maxIndex >= numPoints) throw new Error('index out of range: ' + maxIndex);
for (const a of attributes) {
if (a.data.length !== numPoints * a.numComponents) throw new Error('attribute size mismatch: ' + a.kind);
} Type guard
const isEncodableMesh = (m: { attributes: any[]; indices: number[] }): boolean =>
m.attributes.every((a) => Array.isArray(a.data) || ArrayBuffer.isView(a.data)) &&
m.indices.every((i) => Number.isInteger(i) && i >= 0); Try / catch
try {
return await encodeMeshAsync(attributes, indices, options);
} catch (e) {
if (String(e?.message).includes('Failed to encode')) {
return await encodeMeshAsync(attributes, indices, { quantizationBits: undefined }); // retry without exotic options
}
throw e;
} Prevention
- Assert attribute buffer sizes equal numPoints * numComponents before encoding.
- Clamp/validate index buffers against the vertex count.
- Avoid NaN/Infinity in vertex data; sanitize before encoding.
- Pin a known-good Draco encoder module version in CI.
When it happens
Trigger: EncodeMeshToDracoBuffer returns <= 0, typically due to invalid/inconsistent attribute data (wrong buffer sizes vs point counts), corrupted indices, or unsupported option combinations passed through options.
Common situations: Manually assembling attribute data with mismatched vertex counts; index buffers referencing vertices beyond the position count; feeding NaN/degenerate data; rare Draco native-library failures on exotic attribute combinations.
Related errors
- Draco: Missing position attribute for encoding.
- Draco codec module is not available
- status.error_msg()
- Draco: Encoder module is not available
- Recast is not initialized. Please call InitRecast first.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/7f8d0f6fbf53cb1a.
Report an issue: GitHub.