{"record":{"id":"4dd4d731e57bd816","repo":"BabylonJS/Babylon.js","slug":"missing-arrays-in-sog-scales-data","errorCode":null,"errorMessage":"Missing arrays in SOG scales data.","messagePattern":"Missing arrays in SOG scales data\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/dev/loaders/src/SPLAT/sog.pure.ts","lineNumber":199,"sourceCode":"    }\r\n\r\n    // --- Scales\r\n    const scales = imageDataArrays[2].bits;\r\n    if (data.version === 2) {\r\n        if (!data.scales.codebook) {\r\n            throw new Error(\"Missing codebook in SOG version 2 scales data.\");\r\n        }\r\n        for (let i = 0; i < splatCount; i++) {\r\n            const index = i * 4;\r\n            for (let j = 0; j < 3; j++) {\r\n                const sc = data.scales.codebook[scales[index + j]];\r\n                const sce = Math.exp(sc);\r\n                scale[i * 8 + 3 + j] = sce;\r\n            }\r\n        }\r\n    } else {\r\n        if (!Array.isArray(data.scales.mins) || !Array.isArray(data.scales.maxs)) {\r\n            throw new Error(\"Missing arrays in SOG scales data.\");\r\n        }\r\n\r\n        for (let i = 0; i < splatCount; i++) {\r\n            const index = i * 4;\r\n            for (let j = 0; j < 3; j++) {\r\n                const sc = scales[index + j];\r\n                const lsc = Scalar.Lerp(data.scales.mins[j], data.scales.maxs[j], sc / 255);\r\n                const lsce = Math.exp(lsc);\r\n                scale[i * 8 + 3 + j] = lsce;\r\n            }\r\n        }\r\n    }\r\n\r\n    // --- Colors/SH0\r\n    const colors = imageDataArrays[4].bits;\r\n    if (data.version === 2) {\r\n        if (!data.sh0.codebook) {\r\n            throw new Error(\"Missing codebook in SOG version 2 sh0 data.\");\r","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/SPLAT/sog.pure.ts#L181-L217","documentation":"In SOG version 1 (non-codebook) files, scales are dequantized per-component via linear interpolation between per-axis mins and maxs arrays stored in meta.json. This error means data.scales.mins or data.scales.maxs is missing or is not an array (SOGDataFile types them as number | number[]; a scalar is only valid for shN), so scale values cannot be reconstructed from the 8-bit image data.","triggerScenarios":"Parsing a SOG bundle (ParseSogMeta) whose meta.json omits mins/maxs on the scales entry, or supplies them as a scalar instead of a 3-element array; also fires when a v2-encoded file has its version field missing/reset so the code falls into the v1 branch.","commonSituations":"Hand-written or trimmed meta.json from an external SOG tool; an encoder bug that emits scalar mins/maxs for scales; version field stripped by a minifier/JSON transform causing v2 data to take the v1 code path.","solutions":["Add the correct 3-element mins/maxs arrays to the scales entry of meta.json (matching what the encoder used for quantization).","If the asset is v2, restore version: 2 in meta.json so the codebook path is used and mins/maxs are not required.","Pre-validate meta.json: Array.isArray(meta.scales.mins) && Array.isArray(meta.scales.maxs) when version !== 2."],"exampleFix":"// before\n\"scales\": { \"shape\": [100000, 3], \"dtype\": \"uint8\", \"files\": [\"scales.webp\"] }\n// after\n\"scales\": { \"shape\": [100000, 3], \"dtype\": \"uint8\", \"files\": [\"scales.webp\"], \"mins\": [-4.2, -4.2, -4.2], \"maxs\": [4.2, 4.2, 4.2] }","handlingStrategy":"validation","validationCode":"function validateV1Scales(meta) {\n  if (meta.version !== 2 &&\n      !(Array.isArray(meta.scales?.mins) && meta.scales.mins.length === 3 &&\n        Array.isArray(meta.scales?.maxs) && meta.scales.maxs.length === 3)) {\n    throw new Error('v1 SOG asset: meta.scales.mins/maxs (3-element arrays) are required');\n  }\n}","typeGuard":"function hasScalesRanges(meta) {\n  return Array.isArray(meta.scales?.mins) && Array.isArray(meta.scales?.maxs) &&\n         meta.scales.mins.length === 3 && meta.scales.maxs.length === 3;\n}","tryCatchPattern":"try {\n  return await ParseSogMeta(metaOrFiles, rootUrl, scene);\n} catch (e) {\n  if (e.message === 'Missing arrays in SOG scales data.') {\n    // meta.scales lacks mins/maxs: asset is malformed for its declared version\n  }\n  throw e;\n}","preventionTips":["Validate the full meta.json against the SOGDataFile schema (mins/maxs arrays per attribute) before loading.","Do not strip 'unknown' fields when transforming meta.json — mins/maxs and codebook are required per version.","Track SOG format version per asset so v1 ranges vs v2 codebooks are not confused."],"tags":["sog","gaussian-splatting","metadata","quantization","asset-validation"],"backgroundTag":"missing-quantization-range-metadata","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}