BabylonJS/Babylon.js · critical
SmartAssetManager: Unknown manager state.
Error message
SmartAssetManager: Unknown manager state.
What it means
GetSmartAssetInternals looked up the manager in the global WeakMap of manager->internals and found nothing. Every public SmartAssetManager function funnels through this lookup, so it indicates the manager instance was not created/registered through the library's own constructor path (e.g. a hand-constructed or deserialized manager object, or one whose internals entry was never attached).
Source
Thrown at packages/dev/core/src/SmartAssets/smartAssetManager.pure.ts:555
internal.textureKeys.clear();
internal.reloadSources.clear();
internal.containers.clear();
for (const blobUrl of Array.from(internal.blobUrls.values())) {
URL.revokeObjectURL(blobUrl);
}
internal.blobUrls.clear();
manager.onChangedObservable.clear();
if (manager.scene.metadata) {
delete manager.scene.metadata[SMART_ASSET_MANAGER_KEY];
}
}
function GetSmartAssetInternals(manager: SmartAssetManager): SmartAssetManagerInternals {
const internal = GetInternalsMap().get(manager);
if (!internal) {
throw new Error("SmartAssetManager: Unknown manager state.");
}
return internal;
}
function RevokeManagedBlobUrl(internal: SmartAssetManagerInternals, key: string, replacementUrl?: string): void {
const blobUrl = internal.blobUrls.get(key);
if (!blobUrl || blobUrl === replacementUrl) {
return;
}
URL.revokeObjectURL(blobUrl);
internal.blobUrls.delete(key);
}
function TrackManagedBlobUrl(internal: SmartAssetManagerInternals, key: string, url: string): void {
if (url.startsWith("blob:")) {
internal.blobUrls.set(key, url);
}
}View on GitHub (pinned to 0592b347b8)
Solutions
- Obtain the manager via GetSmartAssetManager(scene) instead of constructing or copying SmartAssetManager instances directly.
- After a hot reload or test setup, re-acquire the manager from the scene rather than reusing a cached old instance.
- In tests, use the real factory (or the library's provided mock/internals hook) instead of a plain-object stub.
- Check that no code path clears the internals map (module re-evaluation) before the manager is used.
Example fix
// before const manager = new SmartAssetManager(); // not tracked in internals WeakMap const all = GetAllSmartAssets(scene); // after const manager = GetSmartAssetManager(scene); // factory-managed instance const all = GetAllSmartAssets(scene);
Defensive patterns
Strategy: try-catch
Validate before calling
function managerIsUsable(manager: unknown): manager is SmartAssetManager {
try {
GetAllSmartAssets(GetSmartAssetManager(scene)); // forces internals lookup
return true;
} catch {
return false;
}
} Type guard
function isTrackedSmartAssetManager(m: unknown): m is SmartAssetManager {
return m instanceof SmartAssetManager && internalsWeakMapHas(m); // if internals map is exported; otherwise probe via a cheap API call in try/catch
} Try / catch
let internal: SmartAssetManagerInternals;
try {
internal = GetSmartAssetInternals(manager);
} catch (e) {
if (e instanceof Error && e.message === 'SmartAssetManager: Unknown manager state.') {
manager = GetSmartAssetManager(scene); // re-acquire factory-managed instance
internal = GetSmartAssetInternals(manager);
} else {
throw e;
}
} Prevention
- Only obtain managers via GetSmartAssetManager(scene); never construct or clone SmartAssetManager manually.
- After hot module reloads, re-acquire the manager instead of caching stale instances.
- In tests, use the library's factory or provided test helpers, not plain-object stubs.
- Avoid structuredClone/postMessage of manager instances — WeakMap-tracked internals do not survive.
- Wrap manager acquisition once at app startup and share that single instance.
When it happens
Trigger: Calling GetSmartAssetInternals-backed APIs (GetAllSmartAssets, FindSmartAssetKeyForObject, loads, unloads) on a SmartAssetManager that was created outside the library's factory (e.g. Object.create(SmartAssetManager.prototype), structuredClone, or a stale instance across a hot reload that lost the WeakMap binding).
Common situations: Hot module reload recreating the WeakMap while an old manager instance survives; mocking or stubbing SmartAssetManager in tests with a plain object; restoring a manager from a serialized snapshot instead of going through GetSmartAssetManager(scene).
Related errors
- SmartAssetManager: Key "${key}" is not registered. Provide a
- Initial color gradient values not found in context.
- No Physics Engine available.
- Plugin version is incorrect. Expected version 2.
- No Physics Plugin available.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/bfa6b134aea3aff2.
Report an issue: GitHub.