BabylonJS/Babylon.js · error
Invalid or empty skeleton provided
Error message
Invalid or empty skeleton provided
What it means
BVHExporter.Export validates its input before building the BVH motion text: the skeleton must exist and contain at least one bone. Otherwise there is no hierarchy to write and the export is aborted. The message also covers a non-null skeleton with zero bones.
Source
Thrown at packages/dev/serializers/src/BVH/bvhSerializer.ts:23
import { Vector3, Quaternion, Matrix } from "core/Maths/math.vector";
import { Tools } from "core/Misc/tools";
import { Epsilon } from "core/Maths/math.constants";
import { type Nullable } from "core/types";
interface IBVHBoneData {
bone: Bone;
children: IBVHBoneData[];
hasPositionChannels: boolean;
hasRotationChannels: boolean;
positionKeys: IAnimationKey[];
rotationKeys: IAnimationKey[];
}
export class BVHExporter {
public static Export(skeleton: Skeleton, animationNames: string[] = [], frameRate?: number): string {
// Validate skeleton
if (!skeleton || skeleton.bones.length === 0) {
throw new Error("Invalid or empty skeleton provided");
}
// If no animation names provided, use all available animations
let animationsToExport = animationNames;
if (!animationNames || animationNames.length === 0) {
animationsToExport = skeleton.animations.map((anim) => anim.name);
}
// 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) {View on GitHub (pinned to 0592b347b8)
Solutions
- Check skeleton && skeleton.bones.length > 0 before calling Export
- Ensure the skeleton was built (e.g. from a mesh or importer) and bones are loaded before exporting
- Verify the scene/skeleton reference is correct (not undefined from a failed scene.getSkeletonByName)
Example fix
// before
const bvh = BVHExporter.Export(scene.getSkeletonByName("rig")!); // may throw
// after
const skel = scene.getSkeletonByName("rig");
if (skel && skel.bones.length > 0) {
const bvh = BVHExporter.Export(skel);
} Defensive patterns
Strategy: validation
Validate before calling
if (!skeleton || skeleton.bones.length === 0) {
throw new Error(`Cannot export BVH: skeleton '${name}' missing or has no bones`);
} Type guard
function isExportableSkeleton(s: Skeleton | null | undefined): s is Skeleton {
return !!s && Array.isArray(s.bones) && s.bones.length > 0;
} Try / catch
try {
const bvh = BVHExporter.Export(skeleton);
} catch (e) {
if (String(e.message).includes("Invalid or empty skeleton")) {
logger.warn("Skipping BVH export: skeleton not built yet", e);
} else throw e;
} Prevention
- Verify skeleton.bones.length > 0 after load and before export
- Check scene.getSkeletonByName return value for undefined (typo guard)
- Ensure importer/buildFromMesh has completed before exporting
When it happens
Trigger: Passing null/undefined to BVHExporter.Export, or a Skeleton instance whose bones array is empty (skeleton created but bones never built, or joints not yet linked).
Common situations: Calling export before skeleton.buildFromMesh / before the skeleton is constructed from a mesh; a scene load that silently failed leaving an empty Skeleton; retrieving a skeleton by name from the scene with a typo and getting undefined.
Related errors
- No animation range found in skeleton
- step size should be less than 1.
- Invalid property (${name}) in property path (${targetPropert
- Invalid property (${this._targetPath}) in property path (${t
- Sample2DRgbaToRef: widthPx and heightPx must be positive.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/115c10877ba52b61.
Report an issue: GitHub.