BabylonJS/Babylon.js · error

Unknown fill mode: ${fillMode}

Error message

Unknown fill mode: ${fillMode}

What it means

GetPrimitiveMode converts a Babylon Material fill mode constant into a glTF primitive mode enum (TRIANGLES, LINES, LINE_STRIP, POINTS, ...). A fillMode outside the known set has no glTF equivalent, so the exporter throws rather than emitting an invalid primitive mode.

Source

Thrown at packages/dev/serializers/src/glTF/2.0/glTFUtilities.ts:167

    switch (fillMode) {
        case Material.TriangleFillMode:
            return MeshPrimitiveMode.TRIANGLES;
        case Material.TriangleStripDrawMode:
            return MeshPrimitiveMode.TRIANGLE_STRIP;
        case Material.TriangleFanDrawMode:
            return MeshPrimitiveMode.TRIANGLE_FAN;
        case Material.PointListDrawMode:
        case Material.PointFillMode:
            return MeshPrimitiveMode.POINTS;
        case Material.LineLoopDrawMode:
            return MeshPrimitiveMode.LINE_LOOP;
        case Material.LineListDrawMode:
            return MeshPrimitiveMode.LINES;
        case Material.LineStripDrawMode:
            return MeshPrimitiveMode.LINE_STRIP;
    }

    throw new Error(`Unknown fill mode: ${fillMode}`);
}

export function IsTriangleFillMode(fillMode: number): boolean {
    switch (fillMode) {
        case Material.TriangleFillMode:
        case Material.TriangleStripDrawMode:
        case Material.TriangleFanDrawMode:
            return true;
    }

    return false;
}

export function NormalizeTangent(tangent: Vector4 | Vector3) {
    const length = Math.sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);
    if (length > 0) {
        tangent.x /= length;
        tangent.y /= length;

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Set material.fillMode to a supported constant (Material.TriangleFillMode, PointListDrawMode, LineListDrawMode, LineStripDrawMode, TriangleStripDrawMode, TriangleFanDrawMode) before export
  2. Temporarily switch the fill mode to Material.TriangleFillMode for the export and restore it afterwards
  3. If using a custom fill mode, map it to the closest supported glTF mode (patch GetPrimitiveMode) or preprocess the mesh accordingly
  4. Catch the error and skip exporting primitives with unsupported fill modes

Example fix

// before
material.fillMode = 42; // unknown
await GLTF2Export.GLTFAsync(scene, "scene"); // throws
// after
material.fillMode = Material.TriangleFillMode;
await GLTF2Export.GLTFAsync(scene, "scene");
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = [Material.TriangleFillMode, Material.PointListDrawMode, Material.TriangleStripDrawMode, Material.TriangleFanDrawMode, Material.LineListDrawMode, Material.LineStripDrawMode];
const hasSupportedFillMode = (mat: Material | null): boolean => !!mat && SUPPORTED.includes(mat.fillMode);

Type guard

function hasValidFillMode(m: Material): boolean {
    return [m.TriangleFillMode, m.PointListDrawMode, m.TriangleStripDrawMode, m.TriangleFanDrawMode, m.LineListDrawMode, m.LineStripDrawMode].includes(m.fillMode);
}

Try / catch

try {
    await GLTF2Export.GLTFAsync(scene, "scene");
} catch (e) {
    if (e instanceof Error && e.message.startsWith("Unknown fill mode:")) {
        // reset material.fillMode to Material.TriangleFillMode and retry
    } else { throw e; }
}

Prevention

When it happens

Trigger: Exporting a mesh whose material.fillMode holds an unrecognized value — e.g. a custom/invalid number assigned to material.fillMode, or a fill mode constant not covered by the switch (point/line modes beyond those mapped, or garbage values) reached via _exportIndices during GLTFExporter export.

Common situations: Manually setting material.fillMode = someUnmappedNumber; custom Material subclasses defining their own fill mode constants; corrupted/legacy scene data where fillMode was serialized as an arbitrary number.

Related errors


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