BabylonJS/Babylon.js · error

maxLODsToLoad must be greater than zero

Error message

maxLODsToLoad must be greater than zero

What it means

MSFT_lod tracks how many LOD levels to load via maxLODsToLoad. _getLODs resolves the LOD id lists for nodes/materials and requires a positive count; a value of zero or negative makes the level computation meaningless, so it throws before returning properties. It is reached whenever any node or material with LOD ids is processed.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/MSFT_lod.pure.ts:368

                    bufferLOD.loaded.resolve(data);
                },
                (error) => {
                    bufferLOD.loaded.reject(error);
                }
            );
        }
    }

    /**
     * @returns an array of LOD properties from lowest to highest.
     * @param context
     * @param property
     * @param array
     * @param ids
     */
    private _getLODs<T>(context: string, property: T, array: ArrayLike<T> | undefined, ids: number[]): T[] {
        if (this.maxLODsToLoad <= 0) {
            throw new Error("maxLODsToLoad must be greater than zero");
        }

        const properties: T[] = [];

        for (let i = ids.length - 1; i >= 0; i--) {
            properties.push(ArrayItem.Get(`${context}/ids/${ids[i]}`, array, ids[i]));
            if (properties.length === this.maxLODsToLoad) {
                return properties;
            }
        }

        properties.push(property);
        return properties;
    }

    private _disposeTransformNode(babylonTransformNode: TransformNode): void {
        const babylonMaterials: Material[] = [];
        const babylonMaterial = (babylonTransformNode as Mesh).material;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Set maxLODsToLoad to at least 1 (e.g. Number.MAX_SAFE_INTEGER to load all LODs).
  2. Remove the MSFT_lod extension from the asset if LODs are unwanted instead of zeroing the count.
  3. Clamp the configured value: maxLODsToLoad = Math.max(1, desired).

Example fix

// before
loader.parent.maxLODsToLoad = 0;
// after
loader.parent.maxLODsToLoad = Number.MAX_SAFE_INTEGER; // or >= 1
Defensive patterns

Strategy: validation

Validate before calling

if (!(loader.parent.maxLODsToLoad > 0)) loader.parent.maxLODsToLoad = 1; // clamp before load

Type guard

function hasValidLodCount(cfg: { maxLODsToLoad: number }): boolean {
  return Number.isInteger(cfg.maxLODsToLoad) && cfg.maxLODsToLoad > 0;
}

Try / catch

try { await loader.loadAsync(url); } catch (e) {
  if (e.message.includes('maxLODsToLoad')) {
    loader.parent.maxLODsToLoad = Number.MAX_SAFE_INTEGER;
    return loader.loadAsync(url);
  } throw e;
}

Prevention

When it happens

Trigger: Setting loader.parent.maxLODsToLoad (or the extension's maxLODsToLoad property) to 0 or a negative number, then loading a glTF that uses the MSFT_lod extension on any node or material.

Common situations: Trying to 'disable' LOD loading by setting maxLODsToLoad = 0; copying a config object where the field was initialized to 0; math computing the value producing 0 or negative.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — 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/88f66cb46b3584d4. Report an issue: GitHub.