stride3d/stride · error · ArgumentOutOfRangeException

blendOperation

Error message

blendOperation

What it means

AnimationBlender's operation-processing switch handles a fixed set of blend operations; the default branch throws ArgumentOutOfRangeException("blendOperation") when the blend operation enum value is outside the known set. It is a guard against corrupt or newer-version animation operation data the blender cannot interpret.

Solutions

  1. Inspect the asset producing the animation operations and fix/remove the invalid blend operation value.
  2. Re-save/reimport the animation asset with the current Stride version.
  3. Extend the switch in AnimationBlender to handle the new enum member if you added one.
  4. Ensure editor and runtime Stride versions match so serialized enum values are valid.

Example fix

// before
default:
    throw new ArgumentOutOfRangeException("blendOperation");

// after (graceful fallback)
default:
    blendOperation = BlendOperation.LinearBlend; // safe default
    break;
Defensive patterns

Strategy: validation

Validate before calling

// Validate blend operation before building animation operations
if (!Enum.IsDefined(typeof(MyBlendOperation), blendOperation))
    throw new InvalidOperationException($"Unknown blend operation: {blendOperation}");

Type guard

bool IsValidBlendOperation(object op) => op is Enum e && Enum.IsDefined(e.GetType(), e);

Try / catch

try { blender.ComputeAnimationBlending(ops, ref result); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "blendOperation") { /* reimport asset / use default blend */ }

Prevention

When it happens

Trigger: ComputeAnimationBlending (or the inner operation loop) encounters an AnimationOperation/blendOperation value not covered by the switch cases at AnimationBlender.cs:286 — i.e. an undefined or out-of-range enum value.

Common situations: Deserializing animation blend data saved by a newer Stride version with added enum members; corrupted or hand-edited animation assets; a new BinaryCurveOperator/blend operation added upstream without updating this switch.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/f3f06c6a03bd6600. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Engine/Animations/AnimationBlender.cs:286

                                    Vector3 rightValue3;
                                    Vector3.Subtract(ref *(Vector3*)sourceLeftData, ref *(Vector3*)sourceRightData, out rightValue3);
                                    Vector3.Lerp(ref *(Vector3*)sourceLeftData, ref rightValue3, blendFactor, out *(Vector3*)resultData);
                                    break;
                                case BlendType.Quaternion:
                                    Quaternion rightValueQ;
                                    // blend between left (0.0) and left * conjugate(right) (1.0)
                                    Quaternion.Invert(ref *(Quaternion*)sourceRightData, out rightValueQ);
                                    Quaternion.Multiply(ref rightValueQ, ref *(Quaternion*)sourceLeftData, out rightValueQ);
                                    Quaternion.Normalize(ref rightValueQ, out rightValueQ);
                                    //throw new NotImplementedException();
                                    Quaternion.Slerp(ref *(Quaternion*)sourceLeftData, ref rightValueQ, blendFactor, out *(Quaternion*)resultData);
                                    break;
                                default:
                                    throw new ArgumentOutOfRangeException();
                            }
                            break;
                        default:
                            throw new ArgumentOutOfRangeException("blendOperation");
                    }
                }
            }
        }

        /// <summary>
        /// Computes the specified animation operations.
        /// </summary>
        /// <param name="animationOperations">The animation operations to perform.</param>
        /// <param name="result">The optional result (if not null, it expects the final stack to end up with this element).</param>
        public void Compute(List<AnimationOperation> animationOperations, ref AnimationClipResult result)
        {
            // Clear animation stack
            animationStack.Clear();

            // Apply first operation (should be a push), directly into result (considered first item in the stack)
            var animationOperation0 = animationOperations[0];

View on GitHub (pinned to 96fad776d2)