BabylonJS/Babylon.js · error · Error
Draco codec module is not available
Error message
Draco codec module is not available
What it means
The DracoCodec constructor checks whether the Draco decoder WASM module is already available in scope. If it is not, and no jsModule override was supplied in the configuration, and no CDN URL is configured to load the module from, the codec cannot ever be initialized and it throws this Error. Draco compression support requires the external draco_decoder WASM script to be present or loadable.
Source
Thrown at packages/dev/core/src/Meshes/Compression/dracoCodec.ts:145
if (useWorkers) {
// eslint-disable-next-line github/no-then
this._workerPoolPromise = codecInfo.wasmBinaryPromise.then((wasmBinary) => {
const workerContent = this._getWorkerContent();
const workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: "application/javascript" }));
// eslint-disable-next-line @typescript-eslint/promise-function-async
return new AutoReleaseWorkerPool(numberOfWorkers, () => {
const worker = new Worker(workerBlobUrl);
return initializeWebWorker(worker, wasmBinary, codecInfo.url);
});
});
} else {
// eslint-disable-next-line github/no-then
this._modulePromise = codecInfo.wasmBinaryPromise.then(async (wasmBinary) => {
if (!this._isModuleAvailable()) {
if (!configuration.jsModule) {
if (!codecInfo.url) {
throw new Error("Draco codec module is not available");
}
await Tools.LoadBabylonScriptAsync(codecInfo.url);
}
}
return await this._createModuleAsync(wasmBinary as ArrayBuffer, configuration.jsModule);
});
}
}
/**
* Returns a promise that resolves when ready. Call this manually to ensure the draco codec is ready before use.
* @returns a promise that resolves when ready
*/
public async whenReadyAsync(): Promise<void> {
if (this._workerPoolPromise) {
await this._workerPoolPromise;
return;
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Load the Draco decoder script first: await Tools.LoadBabylonScriptAsync('https://preview.babylonjs.com/draco_decoder.js') (or include the <script> tag) before creating the codec.
- Set configuration.jsModule to an already-imported Draco decoder module to bypass script loading.
- Set a valid codecInfo.url / configuration so the loader can fetch the decoder, and ensure the URL is reachable from your environment.
- Ensure wasmBinary / decoder files are served locally and DracoCompression.URLPrefix points at them for offline apps.
Example fix
// before
const codec = await DracoCodec.GetAsync(); // throws: module never loaded, no url
// after
import DracoDecoderModule from 'draco3dgltf';
const codec = await DracoCodec.GetAsync({ jsModule: DracoDecoderModule }); Defensive patterns
Strategy: fallback
Validate before calling
// ensure the Draco decoder module is loadable before using Draco compression
if (typeof DracoDecoderModule === 'undefined' && !dracoConfig?.jsModule && !dracoConfig?.url) {
throw new Error('Draco decoder unavailable: provide configuration.jsModule or a reachable url');
} Type guard
const isDracoReady = (cfg: unknown): cfg is { jsModule: Function } =>
!!cfg && typeof (cfg as any).jsModule === 'function'; Try / catch
try {
geometry = await DracoCompression.DecodeMeshToGeometryAsync(name, scene, meshData);
} catch (e) {
if (String(e?.message).includes('Draco codec module is not available')) {
await Tools.LoadBabylonScriptAsync('https://cdn.babylonjs.com/draco_decoder.js');
geometry = await DracoCompression.DecodeMeshToGeometryAsync(name, scene, meshData);
} else { throw e; }
} Prevention
- Include the draco_decoder.js script tag or import draco3dgltf and pass jsModule explicitly.
- Self-host the WASM decoder and set the configuration URL for offline/air-gapped apps.
- Warm up DracoCompression.GetAsync() at startup so failures surface early.
- Keep the decoder module version in sync with your encoder.
When it happens
Trigger: Using DracoCompression / loading a .draco or glTF with Draco extension when the Draco decoder script was never loaded, configuration.jsModule is not provided, and codecInfo.url is falsy (no CDN/default URL configured and Tools.LoadBabylonScriptAsync cannot be attempted).
Common situations: Bundling apps with tree-shaking that strips the side-effect script load; offline/air-gapped environments where the default CDN is unreachable and no local URL is given; custom build pipelines that exclude babylonjs-draco decoder scripts; misconfigured DracoCompressionConfiguration.
Related errors
- twgsl is not available.
- Draco: Failed to encode.
- status.error_msg()
- Draco: Decoder module is not available
- Draco: Decoder module is not available
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/63dc1787e125bd9f.
Report an issue: GitHub.