{"record":{"id":"f19f1caba6def22c","repo":"BabylonJS/Babylon.js","slug":"smartassetmanager-key-key-is-not-registered","errorCode":null,"errorMessage":"SmartAssetManager: Key \"${key}\" is not registered. Provide a URL to auto-register.","messagePattern":"SmartAssetManager: Key \"(.+?)\" is not registered\\. Provide a URL to auto-register\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/SmartAssets/smartAssetManager.pure.ts","lineNumber":245,"sourceCode":" * @param url - Optional URL. If provided, the key is registered first.\n * @param options - Optional loader hints and metadata for this asset.\n * @returns A promise resolving to the loaded AssetContainer.\n */\nexport async function LoadSmartAssetAsync(scene: Scene, key: string, url?: string, options?: SmartAssetLoadOptions): Promise<AssetContainer> {\n    const manager = GetSmartAssetManager(scene);\n    const internal = GetSmartAssetInternals(manager);\n    const previousUrl = internal.urls.get(key);\n    const { reloadSource, ...registrationOptions } = options ?? {};\n    if (url) {\n        RegisterSmartAsset(scene, key, url, registrationOptions);\n    }\n    if (reloadSource) {\n        internal.reloadSources.set(key, reloadSource);\n    }\n\n    const resolvedUrl = internal.urls.get(key);\n    if (!resolvedUrl) {\n        throw new Error(`SmartAssetManager: Key \"${key}\" is not registered. Provide a URL to auto-register.`);\n    }\n\n    const existing = internal.containers.get(key);\n    if (existing) {\n        if (url && url !== previousUrl) {\n            // URL changed — drop the stale container before fetching the new one\n            // so callers don't get a surprise cached return for an updated URL.\n            await UnloadSmartAssetAsync(scene, key);\n        } else {\n            return existing;\n        }\n    }\n\n    return await LoadSmartAssetSceneFileAsync(manager, key, resolvedUrl, internal.options.get(key)?.extension);\n}\n\n/**\n * Loads all registered assets concurrently.","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/SmartAssets/smartAssetManager.pure.ts#L227-L263","documentation":"LoadSmartAssetAsync was called with a key that has no URL registered in the SmartAssetManager's internal registry, and no url argument was supplied to auto-register it. The manager only serves assets whose key->URL mapping was previously added via RegisterSmartAsset (or a prior load with a url). Without a resolved URL it cannot fetch anything, so it throws rather than silently returning an empty container.","triggerScenarios":"LoadSmartAssetAsync(scene, key) with a key never registered via RegisterSmartAsset; calling with a key that was just removed by UnloadSmartAssetAsync (which deletes urls/options/containers for the key, see lines 206-210); a typo'd or renamed key; calling load before project deserialization populated the registry (e.g. DeserializeSmartAssetMap result not applied); loading on a different scene's manager than the one where assets were registered.","commonSituations":"Loading a saved project where the asset map failed to deserialize or was loaded into another scene; renaming an asset key in one place but not the other; calling ReloadSmartAssetAsync after the key was unloaded; hand-written load calls using keys from an older project file whose registrations were dropped.","solutions":["Pass the URL so the key auto-registers: LoadSmartAssetAsync(scene, key, url).","Check the key exists before loading with GetAllSmartAssets(scene).has(key); register it first via RegisterSmartAsset if missing.","Verify the key string against the registered keys (typos/renames are the most common cause).","Ensure you are using the SmartAssetManager for the correct Scene — registrations are per-scene and will not be found on a different scene's manager.","If the key was intentionally unloaded, re-register it before the next load/reload call."],"exampleFix":"// before\nconst container = await LoadSmartAssetAsync(scene, \"player-model\");\n// after\nif (!GetAllSmartAssets(scene).has(\"player-model\")) {\n    RegisterSmartAsset(scene, \"player-model\", \"https://cdn.example.com/player.glb\");\n}\nconst container = await LoadSmartAssetAsync(scene, \"player-model\");","handlingStrategy":"validation","validationCode":"function ensureSmartAssetRegistered(scene: Scene, key: string): boolean {\n    return GetAllSmartAssets(scene).has(key);\n}\n// call site:\nif (!ensureSmartAssetRegistered(scene, key)) {\n    RegisterSmartAsset(scene, key, url);\n}\nconst container = await LoadSmartAssetAsync(scene, key);","typeGuard":null,"tryCatchPattern":"try {\n    container = await LoadSmartAssetAsync(scene, key);\n} catch (e) {\n    if (e instanceof Error && e.message.includes('is not registered')) {\n        container = await LoadSmartAssetAsync(scene, key, fallbackUrls[key]);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always call RegisterSmartAsset (or pass a url to the load call) before loading a key.","Check GetAllSmartAssets(scene).has(key) before any load or reload.","Centralize key names in a constants module to avoid typos and renames drifting.","Remember UnloadSmartAssetAsync deletes the registration — re-register after unloading.","Keep registration and load on the same Scene instance."],"tags":["smart-assets","asset-loading","unregistered-key","babylon"],"backgroundTag":"asset-key-not-registered","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}