{"record":{"id":"fa25aee37f753bf2","repo":"BabylonJS/Babylon.js","slug":"meshinvalidpositionserror","errorCode":"MeshInvalidPositionsError","errorMessage":"Positions are required","messagePattern":"Positions are required","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Meshes/mesh.vertexData.ts","lineNumber":1279,"sourceCode":"                ret[i] = source[i];\r\n            }\r\n            transform && transformRange(ret, transform, 0, source.length);\r\n\r\n            let offset = source.length;\r\n            for (const [vertexData, transform] of nonNullOthers) {\r\n                for (let i = 0; i < vertexData.length; i++) {\r\n                    ret[offset + i] = vertexData[i];\r\n                }\r\n                transform && transformRange(ret, transform, offset, vertexData.length);\r\n                offset += vertexData.length;\r\n            }\r\n            return ret;\r\n        }\r\n    }\r\n\r\n    private _validate(): void {\r\n        if (!this.positions) {\r\n            throw new RuntimeError(\"Positions are required\", ErrorCodes.MeshInvalidPositionsError);\r\n        }\r\n\r\n        const getElementCount = (kind: string, values: FloatArray) => {\r\n            const stride = VertexBufferDeduceStride(kind);\r\n            if (values.length % stride !== 0) {\r\n                throw new Error(\"The \" + kind + \"s array count must be a multiple of \" + stride);\r\n            }\r\n\r\n            return values.length / stride;\r\n        };\r\n\r\n        const positionsElementCount = getElementCount(VertexBuffer.PositionKind, this.positions);\r\n\r\n        const validateElementCount = (kind: string, values: FloatArray) => {\r\n            const elementCount = getElementCount(kind, values);\r\n            if (elementCount !== positionsElementCount) {\r\n                throw new Error(\"The \" + kind + \"s element count (\" + elementCount + \") does not match the positions count (\" + positionsElementCount + \")\");\r\n            }\r","sourceCodeStart":1261,"sourceCodeEnd":1297,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Meshes/mesh.vertexData.ts#L1261-L1297","documentation":"VertexData._validate() runs during merge (and applyToMesh) and enforces that the VertexData has a positions array; geometry without positions cannot be turned into a mesh. A RuntimeError with code MeshInvalidPositionsError is thrown when positions is null/undefined or empty.","triggerScenarios":"Calling vertexData.merge(other, ...) or mergedVertexData._mergeCoroutine result validation when one of the VertexData objects (or the accumulated one) has no positions, e.g. an empty mesh or a VertexData built from only normals/uvs.","commonSituations":"Merging meshes one of which was created empty (MeshBuilder called with zero positions) or whose positions were disposed; constructing VertexData manually and forgetting set positions; deserialization failures leaving positions undefined.","solutions":["Ensure every VertexData/mesh in the merge has a non-empty positions array before calling merge","Skip empty meshes in the merge list instead of including them","When building VertexData manually, assign `vertexData.positions = [...]` before merging/applying"],"exampleFix":"// before\nconst empty = new VertexData(); // no positions\nvd.merge(empty, true, true, undefined, false); // throws MeshInvalidPositionsError\n// after\nif (empty.positions && empty.positions.length > 0) {\n  vd.merge(empty, true, true, undefined, false);\n}","handlingStrategy":"validation","validationCode":"function hasPositions(vd: BABYLON.VertexData): boolean {\n  return Array.isArray(vd.positions) || (vd.positions instanceof Float32Array && vd.positions.length > 0);\n}\nif (!hasPositions(vd)) throw new Error(\"refusing to merge: no positions\");","typeGuard":"const hasValidPositions = (vd: BABYLON.VertexData): vd is BABYLON.VertexData & { positions: number[] | Float32Array } =>\n  !!vd.positions && (vd.positions as ArrayLike<number>).length > 0;","tryCatchPattern":"import { RuntimeError, ErrorCodes } from \"@babylonjs/core\";\ntry {\n  vd.applyToMesh(mesh);\n} catch (e) {\n  if (e instanceof RuntimeError && (e as RuntimeError).errorCode === ErrorCodes.MeshInvalidPositionsError) {\n    // rebuild/skip this VertexData\n  } else { throw e; }\n}","preventionTips":["Check positions existence and length before merge/applyToMesh","Skip empty or disposed meshes in merge lists","Assign positions before any VertexData use when building manually","Validate deserialized VertexData immediately after load"],"tags":["babylonjs","vertexdata","positions","validation"],"backgroundTag":"missing-mesh-positions","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}