BabylonJS/Babylon.js · error

SmartAssetSerializer: Invalid entry for key "${key}" — expec

Error message

SmartAssetSerializer: Invalid entry for key "${key}" — expected an object.

What it means

DeserializeSmartAssetMap iterates each key of doc.assets and requires every entry to be a non-null object. This error is thrown when an individual asset entry is null, undefined, or a primitive (string/number/boolean), so the deserializer cannot read fields like url from it.

Source

Thrown at packages/dev/core/src/SmartAssets/smartAssetSerializer.ts:59

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.
 * @param url - The URL to inspect.
 * @returns Whether the URL is absolute or a data/blob URI.
 */
export function IsAbsoluteOrSpecialUrl(url: string): boolean {
    return url.startsWith("data:") || url.startsWith("blob:") || Tools.IsAbsoluteUrl(url);
}

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Open the asset-map JSON and fix the offending key so its value is an object, e.g. {"logo": {"url": "https://..."}} instead of {"logo": "https://..."}.
  2. Remove null/undefined entries from doc.assets before deserializing, or filter them with a pre-validation pass.
  3. If another tool produces this file, update or fix the exporter so each asset entry is serialized as an object with a url property.
  4. Wrap deserialization in error handling that surfaces the offending key (it is included in the message) to locate and repair the entry quickly.

Example fix

// before
const doc = { version: 1, assets: { logo: "https://cdn/logo.png", badge: null } };
DeserializeSmartAssetMap(doc);

// after
const doc = {
  version: 1,
  assets: {
    logo: { url: "https://cdn/logo.png" },
    badge: { url: "https://cdn/badge.png" }
  }
};
DeserializeSmartAssetMap(doc);
Defensive patterns

Strategy: type-guard

Validate before calling

const invalid = Object.entries(doc.assets ?? {}).filter(([, v]) => v === null || typeof v !== "object");
if (invalid.length) throw new Error(`Asset entries must be objects: ${invalid.map(([k]) => k).join(", ")}`);

Type guard

function isAssetEntry(v: unknown): v is Record<string, unknown> {
  return typeof v === "object" && v !== null && !Array.isArray(v);
}

Try / catch

try {
  const map = DeserializeSmartAssetMap(doc);
} catch (e) {
  const m = e.message.match(/Invalid entry for key "([^"]+)"/);
  if (m) {
    console.error(`Asset entry "${m[1]}" is not an object; fix or remove it in the asset map.`);
  } else throw e;
}

Prevention

When it happens

Trigger: Any entry value inside doc.assets is null, undefined, a bare string URL (e.g. {"logo": "https://..."}), or a number/boolean. Detected in the for-loop over Object.entries(assets) when (!entry || typeof entry !== "object").

Common situations: Manually authored asset maps where someone wrote the URL string directly as the value instead of an object with a 'url' field; JSON produced by string templates that emitted null for missing assets; a schema change in an external asset pipeline that flattened entries from objects to strings; corrupted export where an entry was dropped to null.

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


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/a57fdf09e1cf95c6. Report an issue: GitHub.