BabylonJS/Babylon.js · error

${context}: Unsupported action ${action}

Error message

${context}: Unsupported action ${action}

What it means

MSFT_audio_emitter animation events map an action enum (stop/pause/play) to a sound callback via _getEventAction. If the event's action value is outside the known enum values, no callback can be built and the loader throws with the numeric action and event context.

Source

Thrown at packages/dev/loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.pure.ts:282

        switch (action) {
            case IMSFTAudioEmitter_AnimationEventAction.play: {
                return (currentFrame: number) => {
                    const frameOffset = (startOffset || 0) + (currentFrame - time);
                    sound.play(frameOffset);
                };
            }
            case IMSFTAudioEmitter_AnimationEventAction.stop: {
                return () => {
                    sound.stop();
                };
            }
            case IMSFTAudioEmitter_AnimationEventAction.pause: {
                return () => {
                    sound.pause();
                };
            }
            default: {
                throw new Error(`${context}: Unsupported action ${action}`);
            }
        }
    }

    // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax
    private _loadAnimationEventAsync(
        context: string,
        animationContext: string,
        animation: IAnimation,
        event: ILoaderAnimationEvent,
        babylonAnimationGroup: AnimationGroup
    ): Promise<void> {
        if (babylonAnimationGroup.targetedAnimations.length == 0) {
            return Promise.resolve();
        }
        const babylonAnimation = babylonAnimationGroup.targetedAnimations[0];
        const emitterIndex = event.emitter;
        const emitter = ArrayItem.Get(`/extensions/${this.name}/emitters`, this._emitters, emitterIndex);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Fix the animation event's action value to a valid enum (0=stop, 1=play, 2=pause).
  2. Re-export the asset with a conformant MSFT_audio_emitter writer.
  3. Remove the offending animation event from the extension data.

Example fix

// before
{ "action": 5, "sound": 0 }
// after
{ "action": 1, "sound": 0 }
Defensive patterns

Strategy: validation

Validate before calling

const VALID_ACTIONS = [0, 1, 2]; // stop, play, pause
events.forEach(ev => { if (!VALID_ACTIONS.includes(ev.action)) throw new Error('Invalid audio emitter action: ' + ev.action); });

Type guard

function hasValidAction(ev: { action: number }): boolean {
  return ev.action === 0 || ev.action === 1 || ev.action === 2;
}

Try / catch

try { await loader.loadAsync(url); } catch (e) {
  if (e.message.includes('Unsupported action')) {
    // sanitize animation event actions to a known enum and retry
  } else throw e;
}

Prevention

When it happens

Trigger: Loading a glTF animation event whose MSFT_audio_emitter extension data has an 'action' value not equal to 0 (stop), 1 (play), or 2 (pause) — e.g. corrupted data or a newer spec revision with unknown action codes.

Common situations: Hand-edited glTF action values; exporters emitting wrong action numbers; assets produced against a draft version of the extension with different enum values.

Related errors


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