{"record":{"id":"72d6b41e0f01c47c","repo":"BabylonJS/Babylon.js","slug":"buffer-data-is-not-available","errorCode":null,"errorMessage":"Buffer data is not available","messagePattern":"Buffer data is not available","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/serializers/src/glTF/2.0/glTFExporter.ts","lineNumber":1027,"sourceCode":"            this._collectBuffers(babylonChildNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsToMeshesMap, state);\r\n        }\r\n    }\r\n\r\n    private _exportBuffers(babylonRootNodes: Node[], state: ExporterState): void {\r\n        const bufferToVertexBuffersMap = new Map<Buffer, VertexBuffer[]>();\r\n        const vertexBufferToMeshesMap = new Map<VertexBuffer, AbstractMesh[]>();\r\n        const morphTargetsMeshesMap = new Map<MorphTarget, AbstractMesh[]>();\r\n\r\n        for (const babylonNode of babylonRootNodes) {\r\n            this._collectBuffers(babylonNode, bufferToVertexBuffersMap, vertexBufferToMeshesMap, morphTargetsMeshesMap, state);\r\n        }\r\n\r\n        const buffers = Array.from(bufferToVertexBuffersMap.keys());\r\n\r\n        for (const buffer of buffers) {\r\n            const data = buffer.getData();\r\n            if (!data) {\r\n                throw new Error(\"Buffer data is not available\");\r\n            }\r\n\r\n            const vertexBuffers = bufferToVertexBuffersMap.get(buffer);\r\n\r\n            if (!vertexBuffers) {\r\n                continue;\r\n            }\r\n\r\n            const byteStride = vertexBuffers[0].byteStride;\r\n            if (vertexBuffers.some((vertexBuffer) => vertexBuffer.byteStride !== byteStride)) {\r\n                throw new Error(\"Vertex buffers pointing to the same buffer must have the same byte stride\");\r\n            }\r\n\r\n            const bytes = DataArrayToUint8Array(data).slice();\r\n\r\n            // Apply normalizations and color corrections to buffer data in-place.\r\n            for (const vertexBuffer of vertexBuffers) {\r\n                const meshes = vertexBufferToMeshesMap.get(vertexBuffer)!;\r","sourceCodeStart":1009,"sourceCodeEnd":1045,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/serializers/src/glTF/2.0/glTFExporter.ts#L1009-L1045","documentation":"This error is thrown by the glTF 2.0 exporter when serializing mesh geometry that references a GPU buffer. The exporter needs the CPU-side data of the buffer (via buffer.getData()) to embed it in the exported glTF, but the buffer has no accessible data (e.g. it is GPU-only/updatable=false, was never populated on CPU, or was already released). The library throws rather than exporting a mesh with missing vertex data.","triggerScenarios":"Calling GLTFExporter export functions (e.g. ExportMeshesAsync / ExportSceneAsync) on a mesh whose VertexBuffer was created without CPU-accessible data, whose buffer data was disposed, or whose Buffer.getData() returns null because the data only lives on the GPU (created with updatable=false and filled via GPU, or created from a typed array later discarded after upload).","commonSituations":"Exporting a scene where meshes were created with new VertexBuffer(engine, ..., updatable=false) and their CPU copies freed; exporting after dispose() was called on geometry; loading meshes via an optimized pipeline that drops CPU buffers; exporting custom meshes whose buffers were set with setDataOnlyOnGPU behavior.","solutions":["Ensure all vertex buffers hold CPU data before exporting: recreate buffers with updatable=true or keep the source typed array so getData() returns data","If meshes were loaded and CPU data was dropped, re-load the assets (or enable keepData/retained CPU copies in the loader) before exporting","Check for disposed geometry: verify buffer.isDisposed()/mesh.geometry before export and rebuild or clone meshes (mesh.clone typically recreates CPU data)","Catch the error and skip/export only meshes with available data"],"exampleFix":"// before\nconst vertexData = new VertexBuffer(engine, positions, VertexBuffer.PositionKind, false); // data may be GPU-only\n// after\nconst vertexData = new VertexBuffer(engine, positions, VertexBuffer.PositionKind, true); // keep CPU copy so getData() returns data for glTF export","handlingStrategy":"validation","validationCode":"function canExportBuffer(buffer: { getData(): Nullable<ArrayBufferView> }): boolean {\n    return !!buffer.getData();\n}\n// before export: verify every mesh's vertex buffers have CPU data\nconst ready = mesh.geometrybuffers.every((b) => b.getData() != null);","typeGuard":"function hasBufferData(b: IBuffer): b is IBuffer & { getData(): ArrayBufferView } {\n    return b.getData() != null;\n}","tryCatchPattern":"try {\n    await GLTF2Export.GLTFAsync(scene, \"scene\");\n} catch (e) {\n    if (e instanceof Error && e.message === \"Buffer data is not available\") {\n        // rebuild CPU-side data or skip the offending mesh\n    } else { throw e; }\n}","preventionTips":["Create vertex buffers with updatable=true or otherwise keep CPU-side copies when the scene will be exported","Never dispose geometry before an export step completes","After loading assets in an optimized mode, confirm getData() returns data before exporting","Write a pre-export validation pass over all meshes and log buffers lacking CPU data"],"tags":["gltf","export","buffer","serialization"],"backgroundTag":"missing-buffer-data","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}