{"record":{"id":"63dc1787e125bd9f","repo":"BabylonJS/Babylon.js","slug":"draco-codec-module-is-not-available","errorCode":null,"errorMessage":"Draco codec module is not available","messagePattern":"Draco codec module is not available","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Meshes/Compression/dracoCodec.ts","lineNumber":145,"sourceCode":"        if (useWorkers) {\r\n            // eslint-disable-next-line github/no-then\r\n            this._workerPoolPromise = codecInfo.wasmBinaryPromise.then((wasmBinary) => {\r\n                const workerContent = this._getWorkerContent();\r\n                const workerBlobUrl = URL.createObjectURL(new Blob([workerContent], { type: \"application/javascript\" }));\r\n\r\n                // eslint-disable-next-line @typescript-eslint/promise-function-async\r\n                return new AutoReleaseWorkerPool(numberOfWorkers, () => {\r\n                    const worker = new Worker(workerBlobUrl);\r\n                    return initializeWebWorker(worker, wasmBinary, codecInfo.url);\r\n                });\r\n            });\r\n        } else {\r\n            // eslint-disable-next-line github/no-then\r\n            this._modulePromise = codecInfo.wasmBinaryPromise.then(async (wasmBinary) => {\r\n                if (!this._isModuleAvailable()) {\r\n                    if (!configuration.jsModule) {\r\n                        if (!codecInfo.url) {\r\n                            throw new Error(\"Draco codec module is not available\");\r\n                        }\r\n                        await Tools.LoadBabylonScriptAsync(codecInfo.url);\r\n                    }\r\n                }\r\n                return await this._createModuleAsync(wasmBinary as ArrayBuffer, configuration.jsModule);\r\n            });\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Returns a promise that resolves when ready. Call this manually to ensure the draco codec is ready before use.\r\n     * @returns a promise that resolves when ready\r\n     */\r\n    public async whenReadyAsync(): Promise<void> {\r\n        if (this._workerPoolPromise) {\r\n            await this._workerPoolPromise;\r\n            return;\r\n        }\r","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Meshes/Compression/dracoCodec.ts#L127-L163","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconst codec = await DracoCodec.GetAsync(); // throws: module never loaded, no url\n\n// after\nimport DracoDecoderModule from 'draco3dgltf';\nconst codec = await DracoCodec.GetAsync({ jsModule: DracoDecoderModule });","handlingStrategy":"fallback","validationCode":"// ensure the Draco decoder module is loadable before using Draco compression\nif (typeof DracoDecoderModule === 'undefined' && !dracoConfig?.jsModule && !dracoConfig?.url) {\n  throw new Error('Draco decoder unavailable: provide configuration.jsModule or a reachable url');\n}","typeGuard":"const isDracoReady = (cfg: unknown): cfg is { jsModule: Function } =>\n  !!cfg && typeof (cfg as any).jsModule === 'function';","tryCatchPattern":"try {\n  geometry = await DracoCompression.DecodeMeshToGeometryAsync(name, scene, meshData);\n} catch (e) {\n  if (String(e?.message).includes('Draco codec module is not available')) {\n    await Tools.LoadBabylonScriptAsync('https://cdn.babylonjs.com/draco_decoder.js');\n    geometry = await DracoCompression.DecodeMeshToGeometryAsync(name, scene, meshData);\n  } else { throw e; }\n}","preventionTips":["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."],"tags":["draco","wasm","compression","missing-dependency"],"backgroundTag":"wasm-module-not-loaded","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}