{"record":{"id":"1bf669a23833aa1b","repo":"BabylonJS/Babylon.js","slug":"failed-to-read-number-of-frames","errorCode":null,"errorMessage":"Failed to read number of frames.","messagePattern":"Failed to read number of frames\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/loaders/src/BVH/bvhLoader.ts","lineNumber":368,"sourceCode":"    // read motion data\n    const motionLine = lines.shift();\n    if (!motionLine || motionLine.trim().toUpperCase() !== _MotionNode) {\n        throw new Error(\"MOTION expected\");\n    }\n\n    const framesLine = lines.shift();\n    if (!framesLine) {\n        throw new Error(\"Unexpected end of file before frame count\");\n    }\n    const framesTokens = framesLine.trim().split(/[\\s]+/);\n    if (framesTokens.length < 2) {\n        throw new Error(\"Invalid frame count line\");\n    }\n\n    // number of frames\n    const numFrames = parseInt(framesTokens[1]);\n    if (isNaN(numFrames)) {\n        throw new Error(\"Failed to read number of frames.\");\n    }\n    context.numFrames = numFrames;\n\n    // frame time\n    const frameTimeLine = lines.shift();\n    if (!frameTimeLine) {\n        throw new Error(\"Unexpected end of file before frame time\");\n    }\n    const frameTimeTokens = frameTimeLine.trim().split(/[\\s]+/);\n    if (frameTimeTokens.length < 3) {\n        throw new Error(\"Invalid frame time line\");\n    }\n    const frameTime = parseFloat(frameTimeTokens[2]);\n    if (isNaN(frameTime)) {\n        throw new Error(\"Failed to read frame time.\");\n    }\n    if (frameTime <= 0) {\n        throw new Error(\"Failed to read frame time. Invalid value \" + frameTime);","sourceCodeStart":350,"sourceCodeEnd":386,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/loaders/src/BVH/bvhLoader.ts#L350-L386","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Replace the token after 'Frames:' with a plain integer matching the actual number of frame data lines in the file (e.g. 'Frames: 120').","Check your BVH generator/template for unsubstituted placeholders ('N', '%d', '{frames}') and fix the substitution.","Verify the count equals the number of motion data lines that follow; mismatched counts cause silent skipped frames even when parsing succeeds.","Pre-validate with /Frames:\\s+(\\d+)\\s*$/ and Number.isInteger(parseInt(match[1])) before calling ReadBvh.","Re-export the file from the original tool if the header was corrupted by manual editing."],"exampleFix":"// before\nMOTION\nFrames: N\nFrame Time: 0.033333\n\n// after\nMOTION\nFrames: 120\nFrame Time: 0.033333","handlingStrategy":"validation","validationCode":"function framesCountIsValid(text: string): boolean {\n    const m = text.match(/Frames:\\s*([^\\r\\n]+)/i);\n    return !!m && Number.isInteger(parseInt(m[1].trim().split(/\\s+/)[0], 10));\n}\nif (!framesCountIsValid(bvhText)) {\n    throw new Error(\"BVH frame count is not a valid integer\");\n}\nconst skeleton = ReadBvh(bvhText, scene, null, options);","typeGuard":null,"tryCatchPattern":"try {\n    const skeleton = ReadBvh(bvhText, scene, null, options);\n} catch (e) {\n    if (e instanceof Error && e.message.startsWith(\"Failed to read number of frames\")) {\n        console.error(\"'Frames:' token is not a number — check generator template\", e);\n    } else {\n        throw e;\n    }\n}","preventionTips":["Search generated BVH templates for unsubstituted placeholders like N, %d, or {frames}.","Assert the declared frame count equals the number of motion data lines in a pre-parse check.","Write frame counts with plain integers; avoid locale formatting or thousands separators in BVH output."],"tags":["bvh","parser","mocap","malformed-header"],"backgroundTag":"bvh-malformed-file","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}