{"record":{"id":"9acf8bb959ad6f23","repo":"BabylonJS/Babylon.js","slug":"expected-channels-definition","errorCode":null,"errorMessage":"Expected CHANNELS definition","messagePattern":"Expected CHANNELS definition","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/BVH/bvhLoader.ts","lineNumber":293,"sourceCode":"    }\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\n            return node;\n        } else if (line) {\n            node.children.push(ReadNode(lines, line, node, context));\n        }","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/BVH/bvhLoader.ts#L275-L311","documentation":"Inside a node body, the line after OFFSET must be a CHANNELS declaration. If the parser reads a line whose first token is not CHANNELS (e.g. \"}\", \"JOINT\", or garbage), it throws because the channel layout is mandatory for every animated node in the BVH format.","triggerScenarios":"A JOINT/ROOT whose body goes straight from OFFSET to \"}\" (channels omitted), or from OFFSET to a child JOINT line; END-node content pasted into a normal joint; a node incorrectly typed as END SITE earlier causing brace/line misalignment downstream.","commonSituations":"Hand-written or hand-trimmed BVH files; custom exporters that skip CHANNELS for leaf joints (spec requires CHANNELS even with 0..3 entries for non-ENDSITE nodes); files from tools using slightly different dialects.","solutions":["Add the required CHANNELS line after each node's OFFSET, e.g. \"CHANNELS 3 Zrotation Xrotation Yrotation\" for leaf joints and 6-channel (position+rotation) sets for roots.","Verify ROOT uses CHANNELS 6 with X/Y/Z position plus rotations; JOINTs use CHANNELS 3 with rotations only, per the standard dialect.","Re-export the file from the original mocap/DCC tool instead of hand-editing.","Check that the token reported in the message is not a stray line (e.g. a duplicated \"}\") that should be removed."],"exampleFix":"// before\nJOINT Chest\n{\n  OFFSET 0.0 8.0 0.0\n}\n// after\nJOINT Chest\n{\n  OFFSET 0.0 8.0 0.0\n  CHANNELS 3 Zrotation Xrotation Yrotation\n}","handlingStrategy":"validation","validationCode":"function assertChannelsAfterOffset(text: string): void {\n  const lines = text.split(/\\r?\\n/).map((l) => l.trim());\n  for (let i = 0; i < lines.length; i++) {\n    if (lines[i].toUpperCase().startsWith(\"OFFSET\")) {\n      const next = lines[i + 1];\n      // for non-ENDSITE nodes the next line inside the body must be CHANNELS\n      if (next && next !== \"}\" && !next.toUpperCase().startsWith(\"CHANNELS\") && !next.toUpperCase().startsWith(\"JOINT\")) {\n        throw new Error(`Line ${i + 2}: expected CHANNELS after OFFSET, got \"${next.split(/\\s+/)[0]}\"`);\n      }\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  const skeleton = ReadBvh(text, scene, null, options);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Expected CHANNELS definition\") {\n    console.error(\"A non-ENDSITE node is missing its CHANNELS declaration.\");\n  } else { throw e; }\n}","preventionTips":["Ensure every ROOT/JOINT body has a CHANNELS line (6 channels for roots, 3 for joints in the standard dialect).","Re-export from the mocap tool rather than editing channel lines by hand.","Use a BVH spec validator on generated files."],"tags":["bvh","parser","file-format","malformed-input"],"backgroundTag":"malformed-bvh-structure","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}