{"record":{"id":"525a2963373aa01a","repo":"BabylonJS/Babylon.js","slug":"unexpected-end-of-file-missing-channels","errorCode":null,"errorMessage":"Unexpected end of file: missing CHANNELS","messagePattern":"Unexpected end of file: missing CHANNELS","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/BVH/bvhLoader.ts","lineNumber":289,"sourceCode":"        throw new Error(\"Expected OFFSET, but got: \" + tokens[0]);\n    }\n    if (tokens.length != 4) {\n        throw new Error(\"OFFSET: Invalid number of values\");\n    }\n\n    const offset = new Vector3(parseFloat(tokens[1]), parseFloat(tokens[2]), parseFloat(tokens[3]));\n\n    if (isNaN(offset.x) || isNaN(offset.y) || isNaN(offset.z)) {\n        throw new Error(\"OFFSET: Invalid values\");\n    }\n\n    node.offset = offset;\n\n    // parse CHANNELS definitions\n    if (node.type != \"ENDSITE\") {\n        tokens = lines.shift()?.trim().split(/\\s+/);\n        if (!tokens) {\n            throw new Error(\"Unexpected end of file: missing CHANNELS\");\n        }\n\n        if (tokens[0].toUpperCase() != \"CHANNELS\") {\n            throw new Error(\"Expected CHANNELS definition\");\n        }\n\n        const numChannels = parseInt(tokens[1]);\n        // Skip CHANNELS and the number of channels\n        node.channels = tokens.splice(2, numChannels);\n        node.children = [];\n    }\n\n    // read children\n    while (lines.length > 0) {\n        const line = lines.shift()?.trim();\n\n        if (line === \"}\") {\n            // Finish reading the node","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/BVH/bvhLoader.ts#L271-L307","documentation":"Every non-ENDSITE BVH node must declare its animation channels with a CHANNELS line inside its braces. If the parser hits end-of-file while reading that line (lines.shift() returns undefined), it throws — the file ended before the node's CHANNELS declaration.","triggerScenarios":"A truncated .bvh that stops after a ROOT/JOINT node's OFFSET line, before CHANNELS or before the MOTION section; a file containing only a HIERARCHY header (skeleton dump) without complete node bodies.","commonSituations":"Streaming/partial downloads of mocap files; exporting tools that abort mid-write; users stripping the MOTION section for static-skeleton use and cutting node bodies instead of just frames; test fixtures trimmed too aggressively.","solutions":["Ensure each JOINT/ROOT body contains OFFSET then CHANNELS then children then \"}\" — restore missing CHANNELS lines (typical: \"CHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation\" for roots).","Re-obtain the full untruncated file (compare line counts with the source).","If intentionally keeping only the skeleton, use a complete HIERARCHY section — cut after the hierarchy's final closing brace, not inside a node.","Wrap the load in try/catch and report the file as truncated to the user."],"exampleFix":"// before (truncated node)\nJOINT Spine\n{\n  OFFSET 0.0 5.0 0.0\n// after\nJOINT Spine\n{\n  OFFSET 0.0 5.0 0.0\n  CHANNELS 3 Zrotation Xrotation Yrotation\n}","handlingStrategy":"validation","validationCode":"function assertBvhHasChannels(text: string): void {\n  const joints = text.split(/\\r?\\n/).filter((l) => /^(ROOT|JOINT)\\s/i.test(l.trim())).length;\n  const channels = text.split(/\\r?\\n/).filter((l) => l.trim().toUpperCase().startsWith(\"CHANNELS\")).length;\n  if (channels < joints) {\n    throw new Error(`Truncated BVH: ${joints} joints but only ${channels} CHANNELS lines.`);\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const skeleton = ReadBvh(text, scene, null, options);\n} catch (e) {\n  if (e instanceof Error && e.message.includes(\"missing CHANNELS\")) {\n    console.error(\"BVH file ends before a node's CHANNELS line - file is truncated.\");\n  } else { throw e; }\n}","preventionTips":["Check file completeness (MOTION section present, braces balanced) before loading.","Never trim test fixtures inside node bodies.","Verify download integrity for large mocap files."],"tags":["bvh","parser","truncated-file","malformed-input"],"backgroundTag":"malformed-bvh-structure","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}