{"record":{"id":"800958e3fa41604e","repo":"BabylonJS/Babylon.js","slug":"no-pbr-material-implementation-loaded","errorCode":null,"errorMessage":"No PBR material implementation loaded","messagePattern":"No PBR material implementation loaded","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/glTF/2.0/glTFLoader.pure.ts","lineNumber":2392,"sourceCode":"    /**\r\n     * Selects the appropriate PBR material implementation for a given glTF material.\r\n     * Uses OpenPBR when the material carries a \"KHR_materials_openpbr\" extension or when\r\n     * the loader-level `useOpenPBR` flag is set; falls back to standard PBR otherwise.\r\n     * @param material The glTF material\r\n     * @returns The matching loaded implementation\r\n     */\r\n    private _selectImplForGltfMaterial(material: IMaterial): Readonly<PBRMaterialImplementation> {\r\n        if (this.parent.useOpenPBR || material.extensions?.[\"KHR_materials_openpbr\"]) {\r\n            const impl = this._pbrMaterialImpls.get(\"openpbr\");\r\n            if (impl) {\r\n                return impl;\r\n            }\r\n        }\r\n        const impl = this._pbrMaterialImpls.get(\"pbr\");\r\n        if (impl) {\r\n            return impl;\r\n        }\r\n        throw new Error(\"No PBR material implementation loaded\");\r\n    }\r\n\r\n    /**\r\n     * Returns the default PBR material implementation used when there is no per-material\r\n     * selection context (e.g. when creating the built-in default material for primitives\r\n     * that have no glTF material assigned).  Prefers OpenPBR when `useOpenPBR` is set.\r\n     * @returns The default loaded implementation\r\n     */\r\n    private _getDefaultImpl(): Readonly<PBRMaterialImplementation> {\r\n        if (this.parent.useOpenPBR) {\r\n            const impl = this._pbrMaterialImpls.get(\"openpbr\");\r\n            if (impl) {\r\n                return impl;\r\n            }\r\n        }\r\n        const impl = this._pbrMaterialImpls.get(\"pbr\") ?? this._pbrMaterialImpls.values().next().value;\r\n        if (impl) {\r\n            return impl;\r","sourceCodeStart":2374,"sourceCodeEnd":2410,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/glTF/2.0/glTFLoader.pure.ts#L2374-L2410","documentation":"The glTF loader delegates PBR material creation to a pluggable implementation registered in _pbrMaterialImpls (e.g. a PBRMaterial-based implementation registered by the side-effect import of the engine-specific loader module). This error means no 'pbr' implementation was registered when the loader tried to create a PBR material — the required implementation module was never loaded.","triggerScenarios":"Using the pure/tree-shaken glTFLoader entry point without importing the module that registers the PBR material implementation; a bundler tree-shaking away the registration side effect; loading materials before the implementation registry is populated.","commonSituations":"Migrating from the monolithic import to modular '@babylonjs/' imports and missing the glTF loader registration import; tree-shaking configurations dropping 'unused' side-effect modules; custom builds that exclude PBRMaterial.","solutions":["Import the glTF loader module that registers the PBR implementation (e.g. '@babylonjs/loaders/glTF/2.0' side-effect import) before loading assets.","Check that your bundler does not tree-shake the registration import (keep it for its side effects).","Verify PBRMaterial and its factory code are included in the bundle.","Ensure the registration happens before SceneLoader.ImportAsync/LoadAsync is called."],"exampleFix":"// before\nimport { GLTFLoader } from \"@babylonjs/loaders/glTF/2.0/GLTFLoader\"; // no impl registered\n// after\nimport \"@babylonjs/loaders/glTF/2.0\"; // registers PBR material impls\nimport { GLTFLoader } from \"@babylonjs/loaders/glTF/2.0/GLTFLoader\";","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const result = await SceneLoader.ImportAsync(\"\", \"model.glb\", scene);\n  return result;\n} catch (e) {\n  if ((e as Error).message === \"No PBR material implementation loaded\") {\n    // import the registration module and retry once\n    await import(\"@babylonjs/loaders/glTF/2.0\");\n    return SceneLoader.ImportAsync(\"\", \"model.glb\", scene);\n  }\n  throw e;\n}","preventionTips":["Always import the full loaders/glTF/2.0 entry point (side-effect import) in modular setups.","Mark loader registration imports as side-effectful so bundlers keep them.","Smoke-test asset loading in CI to catch missing registrations early.","Register implementations before any async load call, not inside render callbacks."],"tags":["gltf","pbr","materials","module-registration","tree-shaking"],"backgroundTag":"missing-module-registration","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}