{"record":{"id":"968b515736899177","repo":"Comfy-Org/ComfyUI","slug":"file3dtosplat-unsupported-ksplat-version-data-0","errorCode":null,"errorMessage":"File3DToSplat: unsupported .ksplat version {data[0]}.{data[1]}","messagePattern":"File3DToSplat: unsupported \\.ksplat version (.+?)\\.(.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"comfy_extras/nodes_gaussian_splat.py","lineNumber":282,"sourceCode":"\n\ndef _parse_splat_gaussian(data: bytes):\n    # antimatter15 .splat: 32-byte records (f32 xyz, f32 scale, u8 rgba, u8 quat as (b-128)/128 wxyz).\n    if len(data) % 32 != 0:\n        raise ValueError(\"File3DToSplat: .splat size is not a multiple of 32 bytes\")\n    rec = np.frombuffer(data, np.dtype([('xyz', '<f4', 3), ('scale', '<f4', 3),\n                                        ('rgba', 'u1', 4), ('quat', 'u1', 4)]))\n    rgba = rec['rgba'].astype(np.float32) / 255.0\n    rot = _norm_quat((rec['quat'].astype(np.float32) - 128.0) / 128.0)            # wxyz\n    return (rec['xyz'].astype(np.float32), rec['scale'].astype(np.float32), rot,\n            rgba[:, 3].copy(), _rgb_to_sh_dc(rgba[:, :3]))\n\n\ndef _parse_ksplat_gaussian(data: bytes):\n    # mkkellogg SplatBuffer: 4096-byte header, N section headers, then per-section splat data. Supports\n    # levels 0 (float) / 1 (half + bucketed positions) / 2 (half, uint8 SH). SH is skipped (base color kept).\n    if data[0] != 0:\n        raise ValueError(f\"File3DToSplat: unsupported .ksplat version {data[0]}.{data[1]}\")\n    max_sections = struct.unpack_from('<I', data, 4)[0]\n    level = struct.unpack_from('<H', data, 20)[0]\n    if level not in _KSPLAT_COMPRESSION:\n        raise ValueError(f\"File3DToSplat: invalid .ksplat compression level {level}\")\n    bc, bs, br, bcol, bshc, default_range = _KSPLAT_COMPRESSION[level]\n\n    parts = []\n    base = 4096 + max_sections * 1024\n    for s in range(max_sections):\n        so = 4096 + s * 1024\n        cnt = struct.unpack_from('<I', data, so + 0)[0]\n        sec_max = struct.unpack_from('<I', data, so + 4)[0]\n        bucket_size = struct.unpack_from('<I', data, so + 8)[0]\n        bucket_count = struct.unpack_from('<I', data, so + 12)[0]\n        block_size = struct.unpack_from('<f', data, so + 16)[0]\n        bucket_store = struct.unpack_from('<H', data, so + 20)[0]\n        scale_range = struct.unpack_from('<I', data, so + 24)[0] or default_range\n        full_buckets = struct.unpack_from('<I', data, so + 32)[0]","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/Comfy-Org/ComfyUI/blob/1c6d8d45b3693bfbb32385b410d813a7fd6be216/comfy_extras/nodes_gaussian_splat.py#L264-L300","documentation":"Raised by _parse_ksplat_gaussian when the first header byte of a detected .ksplat file (the major version) is not 0. The parser implements the mkkellogg SplatBuffer format with major version 0 (bytes 0/1 are CurrentMajorVersion/CurrentMinorVersion); a non-zero major version means the file was written by an incompatible newer generation of the format.","triggerScenarios":"File3DToSplat on a .ksplat exported by a newer version of the mkkellogg GaussianSplats3D/SplatBuffer library that bumped the major version, or on a binary that merely misdetects as ksplat (first byte 0 and second byte >= 1) but is not a ksplat at all.","commonSituations":"Version drift: viewer/library updated on the producing side while the parser supports only 0.x; passing an arbitrary binary whose first two bytes coincidentally match the ksplat heuristic.","solutions":["Re-export the file as .ply or .spz from the producing tool instead of .ksplat.","Downgrade/align the producing library to a version that writes ksplat major version 0.","Check ComfyUI updates: a newer build may add support for the bumped ksplat version."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"data = open(path, 'rb').read()\nif len(data) >= 2 and data[0] != 0:\n    raise ValueError(f'ksplat major version {data[0]} unsupported (need 0.x)')","typeGuard":"def is_ksplat_v0(data: bytes) -> bool:\n    return len(data) >= 2 and data[0] == 0 and data[1] >= 1","tryCatchPattern":"try:\n    result = _parse_ksplat_gaussian(data)\nexcept ValueError as e:\n    if 'unsupported .ksplat version' in str(e):\n        convert_to_ply_with_source_tool(path)\n    else:\n        raise","preventionTips":["Prefer .ply or .spz for interchange; keep .ksplat only from writers matching version 0.x.","Pin the producing viewer/library version when generating ksplat assets."],"tags":["gaussian-splatting","ksplat","version-mismatch","file-format"],"backgroundTag":null,"analyzedSha":"1c6d8d45b3693bfbb32385b410d813a7fd6be216","analyzedAt":"2026-08-14T19:37:18.893Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}