AnimationAction.crossFadeTo not working?

I have a Three.js scene defined using Lume (3D HTML elements), loading the default animated character from Three’s animation blending example. When it has loaded the GLTF model (the <lume-gltf-model> element uses GLTFLoader under the hood) my plain Three.js code subsequently creates an AnimationMixer and uses mixer.clipAction(model.animations[0])/etc to initiate the animations.

When I run

// broken
walkAction.crossFadeTo(idleAction, 1)

it fades the walk animation to the rest T-pose for some reason.

If I instead use my own fade function, it works:

// use custom function instead (it works!)
crossFadeActions(walkAction, idleAction, 1000)

/** Cross fade between two actions linearly over the given duration in seconds. */
function crossFadeActions(fromAction, toAction, duration) {
	Motor.addRenderTask((t, dt) => {
		const portion = dt / duration
		toAction.weight += portion
		fromAction.weight -= portion
		if (fromAction.weight <= 0) {
			fromAction.weight = 0
			toAction.weight = 1
			return false

(Motor.addRenderTask is a small wrapper around requestAnimationFrame, providing dt out of the box).

The question is, why would my custom crossFadeActions function work fine, but Three’s crossFadeTo not?

Here’s a live demo, where inside the player.on('MODEL_LOAD', ({model}) => { event handler is plain Three.js code to wire up the model’s animations (model is the object created by GLTFLoader, containing model.scene, model.animations, etc).

If you comment out the call to crossFadeActions(walkAction, idleAction, 1000) and uncomment the call to walkAction.crossFadeTo(idleAction, 1) and rerun the demo, you’ll see the issue.

Here’s the example with the Three.js line uncommented, not working:

Try this:

idleAction.weight = 1;
walkAction.crossFadeTo(idleAction, 1);

That works, but why? Isn’t a cross fade supposed to animate one to 0, and the other to 1? Is it a bug?

Here the same demo with your workaround applied, working: