BabylonJS/Babylon.js · error

No animation range found in skeleton

Error message

No animation range found in skeleton

What it means

Export needs an animation frame range (from/to frames) to emit BVH MOTION frames. When no range was supplied via skeleton.getAnimationRange for the target animation and no fallback animation range could be found (no animations, or animations have no registered ranges), the exporter throws because it cannot determine the frame count or timing.

Source

Thrown at packages/dev/serializers/src/BVH/bvhSerializer.ts:48

        }

        // Calculate overall animation range from all specified animations
        let overallRange: Nullable<AnimationRange> = null;
        for (const animName of animationsToExport) {
            const range = skeleton.getAnimationRange(animName);
            if (range) {
                overallRange = overallRange ? new AnimationRange("animation-range", Math.min(overallRange.from, range.from), Math.max(overallRange.to, range.to)) : range;
            }
        }

        if (!overallRange) {
            // If no animation range found, try to get from any animation
            if (skeleton.animations.length > 0) {
                overallRange = skeleton.getAnimationRange(skeleton.animations[0].name);
            }

            if (!overallRange) {
                throw new Error("No animation range found in skeleton");
            }
        }

        // Calculate frame rate from animation data if not provided
        const actualFrameRate = frameRate || 1 / (skeleton.animations[0]?.framePerSecond || 30);

        // Build bone hierarchy and collect animation data
        const boneHierarchy = this._BuildBoneHierarchy(skeleton, animationsToExport);

        // Calculate frame count from actual animation keyframes
        let frameCount = 0;
        for (const boneData of boneHierarchy) {
            if (boneData.positionKeys.length > 0) {
                frameCount = Math.max(frameCount, boneData.positionKeys.length);
            }
            if (boneData.rotationKeys.length > 0) {
                frameCount = Math.max(frameCount, boneData.rotationKeys.length);
            }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Ensure an animation range exists: skeleton.createAnimationRange(name, from, to) or verify with skeleton.getAnimationRange(name) before export
  2. Pass a valid animation name that actually exists in skeleton.animations
  3. Pass an explicit frameRate and ensure at least one animation with a range is present

Example fix

// before
BVHExporter.Export(skeleton, ["walk"]); // throws if 'walk' has no range
// after
skeleton.createAnimationRange("walk", 0, 60);
BVHExporter.Export(skeleton, ["walk"]);
Defensive patterns

Strategy: validation

Validate before calling

const range = skeleton.getAnimationRange(animName)
  ?? (skeleton.animations.length > 0 ? skeleton.getAnimationRange(skeleton.animations[0].name) : null);
if (!range) throw new Error(`no animation range for '${animName}'; call skeleton.createAnimationRange(...)`);

Try / catch

try {
  const bvh = BVHExporter.Export(skeleton, [animName]);
} catch (e) {
  if (String(e.message).includes("No animation range")) {
    skeleton.createAnimationRange(animName, 0, frameCount - 1);
    bvh = BVHExporter.Export(skeleton, [animName]);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling Export with animationNames pointing at an animation that has no AnimationRange registered in the skeleton, and the fallback (skeleton.animations[0]) is also missing or range-less; animations attached but never played/registered so getAnimationRange returns null.

Common situations: Ranges cleared by stopAnimation/cleanup; animations imported without range metadata; passing a wrong animation name string; a skeleton cloned without carrying animation ranges.

Related errors


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