BabylonJS/Babylon.js · error · Error

${context}: Invalid number of components (${componentSize})

Error message

${context}: Invalid number of components (${componentSize}) for COLOR_0 attribute

What it means

Morph target COLOR_0 attributes must have 3 (RGB) or 4 (RGBA) components. When _loadMorphTargetVertexDataAsync builds the color Float32Array for a morph target and the per-vertex component size is anything else, it throws because Babylon colors can only be set as Vec3/Vec4 data.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/glTFLoader.pure.ts:1471

            let colors = null;
            const componentSize = babylonVertexBuffer.getSize();
            if (componentSize === 3) {
                colors = new Float32Array((data.length / 3) * 4);
                babylonVertexBuffer.forEach(data.length, (value, index) => {
                    const pixid = Math.floor(index / 3);
                    const channel = index % 3;
                    colors[4 * pixid + channel] = data[3 * pixid + channel] + value;
                });
                for (let i = 0; i < data.length / 3; ++i) {
                    colors[4 * i + 3] = 1;
                }
            } else if (componentSize === 4) {
                colors = new Float32Array(data.length);
                babylonVertexBuffer.forEach(data.length, (value, index) => {
                    colors[index] = data[index] + value;
                });
            } else {
                throw new Error(`${context}: Invalid number of components (${componentSize}) for COLOR_0 attribute`);
            }
            babylonMorphTarget.setColors(colors);
        });

        return await Promise.all(promises).then(() => {});
    }

    private static _LoadTransform(node: INode, babylonNode: TransformNode): void {
        // Ignore the TRS of skinned nodes.
        // See https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins (second implementation note)
        if (node.skin != undefined) {
            return;
        }

        let position = Vector3.Zero();
        let rotation = Quaternion.Identity();
        let scaling = Vector3.One();

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Fix the asset so COLOR_0 accessors are type VEC3 or VEC4 (as the glTF spec requires)
  2. Run the file through glTF-Validator to catch invalid accessor types before loading
  3. Re-export the model and confirm color attribute types in the output JSON

Example fix

// before (in .gltf)
// { "attributes": { "COLOR_0": 7 }, ... } // accessor 7 type: VEC2
// after
// accessor 7: { "type": "VEC4", "componentType": 5126 } // 3 or 4 components required
Defensive patterns

Strategy: validation

Validate before calling

// Check COLOR_0 accessor types on morph targets before loading
for (const mesh of gltf.meshes ?? []) {
  for (const p of mesh.primitives ?? []) {
    for (const t of p.targets ?? []) {
      if (t.COLOR_0 != null) {
        const acc = gltf.accessors[t.COLOR_0];
        if (!/^VEC[34]$/.test(acc.type)) throw new Error(`COLOR_0 accessor must be VEC3/VEC4, got ${acc.type}`);
      }
    }
  }
}

Type guard

function hasValidColorAccessor(gltf, accessorIndex) {
  const acc = gltf.accessors?.[accessorIndex];
  return !!acc && (acc.type === "VEC3" || acc.type === "VEC4");
}

Try / catch

try {
  await loader.loadAsync(url);
} catch (e) {
  if (e.message.includes("Invalid number of components") && e.message.includes("COLOR_0")) {
    console.error("Fix morph target COLOR_0 accessor to VEC3/VEC4");
  } else throw e;
}

Prevention

When it happens

Trigger: Loading a glTF whose morph target's COLOR_0 accessor has componentType/Type yielding componentSize other than 3 or 4 (e.g. a VEC2 or scalar color accessor).

Common situations: Hand-authored glTF with a malformed COLOR_0 accessor type; asset-conversion scripts that rewrite accessors incorrectly; exporter bugs emitting unsupported color vector sizes.

Related errors


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