BabylonJS/Babylon.js · error · Error

Unexpected end of file: missing CHANNELS

Error message

Unexpected end of file: missing CHANNELS

What it means

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.

Source

Thrown at packages/dev/loaders/src/BVH/bvhLoader.ts:289

        throw new Error("Expected OFFSET, but got: " + tokens[0]);
    }
    if (tokens.length != 4) {
        throw new Error("OFFSET: Invalid number of values");
    }

    const offset = new Vector3(parseFloat(tokens[1]), parseFloat(tokens[2]), parseFloat(tokens[3]));

    if (isNaN(offset.x) || isNaN(offset.y) || isNaN(offset.z)) {
        throw new Error("OFFSET: Invalid values");
    }

    node.offset = offset;

    // parse CHANNELS definitions
    if (node.type != "ENDSITE") {
        tokens = lines.shift()?.trim().split(/\s+/);
        if (!tokens) {
            throw new Error("Unexpected end of file: missing CHANNELS");
        }

        if (tokens[0].toUpperCase() != "CHANNELS") {
            throw new Error("Expected CHANNELS definition");
        }

        const numChannels = parseInt(tokens[1]);
        // Skip CHANNELS and the number of channels
        node.channels = tokens.splice(2, numChannels);
        node.children = [];
    }

    // read children
    while (lines.length > 0) {
        const line = lines.shift()?.trim();

        if (line === "}") {
            // Finish reading the node

View on GitHub (pinned to 0592b347b8)

Solutions

  1. 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).
  2. Re-obtain the full untruncated file (compare line counts with the source).
  3. If intentionally keeping only the skeleton, use a complete HIERARCHY section — cut after the hierarchy's final closing brace, not inside a node.
  4. Wrap the load in try/catch and report the file as truncated to the user.

Example fix

// before (truncated node)
JOINT Spine
{
  OFFSET 0.0 5.0 0.0
// after
JOINT Spine
{
  OFFSET 0.0 5.0 0.0
  CHANNELS 3 Zrotation Xrotation Yrotation
}
Defensive patterns

Strategy: validation

Validate before calling

function assertBvhHasChannels(text: string): void {
  const joints = text.split(/\r?\n/).filter((l) => /^(ROOT|JOINT)\s/i.test(l.trim())).length;
  const channels = text.split(/\r?\n/).filter((l) => l.trim().toUpperCase().startsWith("CHANNELS")).length;
  if (channels < joints) {
    throw new Error(`Truncated BVH: ${joints} joints but only ${channels} CHANNELS lines.`);
  }
}

Try / catch

try {
  const skeleton = ReadBvh(text, scene, null, options);
} catch (e) {
  if (e instanceof Error && e.message.includes("missing CHANNELS")) {
    console.error("BVH file ends before a node's CHANNELS line - file is truncated.");
  } else { throw e; }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/525a2963373aa01a. Report an issue: GitHub.