BabylonJS/Babylon.js · error
SmartAssetSerializer: Invalid asset map — 'assets' must be a
Error message
SmartAssetSerializer: Invalid asset map — 'assets' must be an object.
What it means
DeserializeSmartAssetMap validates the shape of a serialized smart-asset map document. After checking the version equals 1, it requires doc.assets to be a plain object (record of key -> entry). This error is thrown when 'assets' is missing, null, not an object, or is an Array, because the deserializer cannot iterate asset entries otherwise.
Source
Thrown at packages/dev/core/src/SmartAssets/smartAssetSerializer.ts:53
/**
* Validates and parses a serialized smart asset map document.
* @param data - The raw data to validate (typically parsed JSON).
* @returns The validated document.
* @throws If the data does not conform to the expected schema.
*/
export function DeserializeSmartAssetMap(data: unknown): ISerializedSmartAssetMap {
if (!data || typeof data !== "object") {
throw new Error("SmartAssetSerializer: Invalid asset map — expected an object.");
}
const doc = data as Record<string, unknown>;
if (doc.version !== 1) {
throw new Error(`SmartAssetSerializer: Unsupported asset map version "${doc.version}". Expected version 1.`);
}
if (!doc.assets || typeof doc.assets !== "object" || Array.isArray(doc.assets)) {
throw new Error("SmartAssetSerializer: Invalid asset map — 'assets' must be an object.");
}
const assets = doc.assets as Record<string, unknown>;
for (const [key, entry] of Object.entries(assets)) {
if (!entry || typeof entry !== "object") {
throw new Error(`SmartAssetSerializer: Invalid entry for key "${key}" — expected an object.`);
}
const entryObj = entry as Record<string, unknown>;
if (typeof entryObj.url !== "string" || entryObj.url.length === 0) {
throw new Error(`SmartAssetSerializer: Invalid entry for key "${key}" — 'url' must be a non-empty string.`);
}
}
return data as ISerializedSmartAssetMap;
}
/**
* Returns true for `data:`, `blob:`, or any URL with an absolute protocol.View on GitHub (pinned to 0592b347b8)
Solutions
- Inspect the JSON document and ensure it has a top-level 'assets' key holding a plain object of key -> {url,...} entries.
- If your data is an array of entries, convert it to a keyed object map before deserializing (e.g. Object.fromEntries(entries.map(e => [e.name, e]))).
- Verify you are passing the correct document (the asset map doc with version:1 and assets), not a parent project object or a sub-field.
- Re-export the asset map from the tool that produced it to regenerate a valid version-1 document.
Example fix
// before
const doc = JSON.parse(raw);
await DeserializeSmartAssetMap(doc); // doc.assets missing / is an array
// after
const parsed = JSON.parse(raw);
const doc = {
version: 1,
assets: Array.isArray(parsed.assets)
? Object.fromEntries(parsed.assets.map(a => [a.name, a]))
: (parsed.assets ?? {})
};
await DeserializeSmartAssetMap(doc); Defensive patterns
Strategy: validation
Validate before calling
function isValidAssetMapDoc(doc) {
return !!doc && typeof doc === "object" &&
doc.version === 1 &&
typeof doc.assets === "object" &&
doc.assets !== null &&
!Array.isArray(doc.assets);
}
if (!isValidAssetMapDoc(parsed)) throw new Error("Not a valid v1 smart-asset map document"); Type guard
function isAssetMapDoc(doc): doc is { version: 1; assets: Record<string, unknown> } {
return typeof doc === "object" && doc !== null &&
(doc as any).version === 1 &&
typeof (doc as any).assets === "object" &&
(doc as any).assets !== null &&
!Array.isArray((doc as any).assets);
} Try / catch
try {
const map = DeserializeSmartAssetMap(doc);
} catch (e) {
if (e.message.includes("'assets' must be an object")) {
console.error("Asset map document malformed: missing or non-object 'assets'", doc);
} else throw e;
} Prevention
- Always produce asset maps through the library's SerializeSmartAssetMap rather than hand-writing JSON.
- Round-trip test (serialize then deserialize) in CI to catch format regressions.
- Never pass JSON arrays where a keyed map is expected; key entries by asset name.
- Validate parsed JSON with a schema (zod/ajv) before deserialization.
When it happens
Trigger: Calling DeserializeSmartAssetMap with a parsed JSON doc where: doc.assets is undefined/omitted; doc.assets is null; doc.assets is an array (e.g. [{...},{...}] instead of {"a": {...}}); or doc.assets is a primitive like a string or number.
Common situations: Hand-edited or truncated asset-map JSON files exported from another tool; a producer exporting assets as a JSON array instead of a keyed map; an older/newer export format where the assets were stored under a different key (e.g. 'assetMap' or nested), leaving doc.assets undefined; template literal string interpolation passing the wrong object level (passing the whole project instead of doc.assets).
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- SmartAssetSerializer: Invalid entry for key "${key}" — expec
- SmartAssetSerializer: Invalid entry for key "${key}" — 'url'
- ProjectFile: Invalid project file — 'overrides' must be an a
- ProjectFile: Invalid project file — 'companionBindings' must
- SmartAssetSerializer: Invalid asset map — expected an object
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/4a5d83daf1608ee6.
Report an issue: GitHub.