BabylonJS/Babylon.js · error

CSG must be used with geometries having the same number of p

Error message

CSG must be used with geometries having the same number of properties

What it means

CSG2 operations (add/subtract/intersect via _process) require both operands to use the same vertex property count (numProp) so Manifold can combine the vertex structures. Mixing geometries with different attribute layouts (e.g. one with UVs/normals and one without) makes the result undefined, so the library throws.

Source

Thrown at packages/dev/core/src/Meshes/csg2.ts:126

    private _numProp: number;
    private _vertexStructure: IManifoldVertexComponent[];

    /**
     * Return the size of a vertex (at least 3 for the position)
     */
    public get numProp() {
        return this._numProp;
    }

    private constructor(manifold: any, numProp: number, vertexStructure: IManifoldVertexComponent[]) {
        this._manifold = manifold;
        this._numProp = numProp;
        this._vertexStructure = vertexStructure;
    }

    private _process(operation: "difference" | "intersection" | "union", csg: CSG2) {
        if (this.numProp !== csg.numProp) {
            throw new Error("CSG must be used with geometries having the same number of properties");
        }
        return new CSG2(Manifold[operation](this._manifold, csg._manifold), this.numProp, this._vertexStructure);
    }

    /**
     * Run a difference operation between two CSG
     * @param csg defines the CSG to use to create the difference
     * @returns a new csg
     */
    public subtract(csg: CSG2) {
        return this._process("difference", csg);
    }

    /**
     * Run an intersection operation between two CSG
     * @param csg defines the CSG to use to create the intersection
     * @returns a new csg
     */

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Build both CSG2 objects from meshes with identical vertex attribute layouts (same enablement of normals/UVs/colors)
  2. Recreate one CSG via CSG2.FromMesh with matching options so numProp aligns
  3. Check csgA.numProp === csgB.numProp before performing the operation

Example fix

// before
const a = CSG2.FromMesh(meshWithUVs);
const b = CSG2.FromMesh(plainBox); // different numProp
a.subtract(b);
// after
const b = CSG2.FromMesh(plainBox, scene, undefined, { sameAttributeOptionsAsMeshWithUVs });
a.subtract(b); // matching numProp
Defensive patterns

Strategy: validation

Validate before calling

if (a.numProp !== b.numProp) {
  throw new Error(`CSG numProp mismatch: ${a.numProp} vs ${b.numProp}; rebuild one operand with matching attributes`);
}

Type guard

const compatible = (a: CSG2, b: CSG2): boolean => a.numProp === b.numProp;

Try / catch

try {
  return a.subtract(b);
} catch (e) {
  if (String(e).includes('same number of properties')) {
    return a.subtract(CSG2.FromMesh(sourceMeshB, scene, undefined, matchingOptions));
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling csgA.subtract(csgB), .add() or .intersect() where the two CSG2 objects were built from meshes with different vertex structures (different number of position/normal/uv/color attributes).

Common situations: Subtracting a primitive (no UVs) from a loaded mesh (with UVs); combining meshes from different importers; enabling/disabling attribute computation inconsistently when creating the CSGs.

Related errors


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