BabylonJS/Babylon.js · error · Error

Failed to read number of frames.

Error message

Failed to read number of frames.

What it means

After finding a 'Frames: <count>' line, ReadBvh parses the second token with parseInt() and throws this error when the result is NaN — i.e. the token after 'Frames:' is not a valid integer. The frame count drives the frame-data loop and animation setup, so a non-numeric count makes the file unparseable.

Source

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

    // read motion data
    const motionLine = lines.shift();
    if (!motionLine || motionLine.trim().toUpperCase() !== _MotionNode) {
        throw new Error("MOTION expected");
    }

    const framesLine = lines.shift();
    if (!framesLine) {
        throw new Error("Unexpected end of file before frame count");
    }
    const framesTokens = framesLine.trim().split(/[\s]+/);
    if (framesTokens.length < 2) {
        throw new Error("Invalid frame count line");
    }

    // number of frames
    const numFrames = parseInt(framesTokens[1]);
    if (isNaN(numFrames)) {
        throw new Error("Failed to read number of frames.");
    }
    context.numFrames = numFrames;

    // frame time
    const frameTimeLine = lines.shift();
    if (!frameTimeLine) {
        throw new Error("Unexpected end of file before frame time");
    }
    const frameTimeTokens = frameTimeLine.trim().split(/[\s]+/);
    if (frameTimeTokens.length < 3) {
        throw new Error("Invalid frame time line");
    }
    const frameTime = parseFloat(frameTimeTokens[2]);
    if (isNaN(frameTime)) {
        throw new Error("Failed to read frame time.");
    }
    if (frameTime <= 0) {
        throw new Error("Failed to read frame time. Invalid value " + frameTime);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Replace the token after 'Frames:' with a plain integer matching the actual number of frame data lines in the file (e.g. 'Frames: 120').
  2. Check your BVH generator/template for unsubstituted placeholders ('N', '%d', '{frames}') and fix the substitution.
  3. Verify the count equals the number of motion data lines that follow; mismatched counts cause silent skipped frames even when parsing succeeds.
  4. Pre-validate with /Frames:\s+(\d+)\s*$/ and Number.isInteger(parseInt(match[1])) before calling ReadBvh.
  5. Re-export the file from the original tool if the header was corrupted by manual editing.

Example fix

// before
MOTION
Frames: N
Frame Time: 0.033333

// after
MOTION
Frames: 120
Frame Time: 0.033333
Defensive patterns

Strategy: validation

Validate before calling

function framesCountIsValid(text: string): boolean {
    const m = text.match(/Frames:\s*([^\r\n]+)/i);
    return !!m && Number.isInteger(parseInt(m[1].trim().split(/\s+/)[0], 10));
}
if (!framesCountIsValid(bvhText)) {
    throw new Error("BVH frame count is not a valid integer");
}
const skeleton = ReadBvh(bvhText, scene, null, options);

Try / catch

try {
    const skeleton = ReadBvh(bvhText, scene, null, options);
} catch (e) {
    if (e instanceof Error && e.message.startsWith("Failed to read number of frames")) {
        console.error("'Frames:' token is not a number — check generator template", e);
    } else {
        throw e;
    }
}

Prevention

When it happens

Trigger: Calling ReadBvh with lines like 'Frames: N', 'Frames: 12a', 'Frames: 1,200' (comma breaks parseInt at '1,200'? actually parseInt('1,200') yields 1 — real triggers are 'Frames: abc', 'Frames: NaN', 'Frames: ??'), or a locale-formatted count such as 'Frames: ١٢٠' or with thousands separators that make the token non-numeric.

Common situations: Template/placeholder text ('Frames: N') left unsubstituted by a generator, hand-edited counts with stray characters, files produced by tools writing 'Frames: %d' due to a formatting bug, or copy-paste corruption where the number was replaced by text.

Related errors


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