stride3d/stride · error · ArgumentOutOfRangeException

index cannot be < 0

Error message

index cannot be < 0

What it means

ModelComponent.GetMaterial throws ArgumentOutOfRangeException when the index passed is negative, because material overrides are keyed by non-negative indices. Indices >= 0 are allowed even if no material exists at them (returns null).

Solutions

  1. Clamp or validate the index to >= 0 before calling GetMaterial.
  2. Fix the caller's loop arithmetic that produces negative indices.
  3. Return early or break loops when the index would go negative instead of querying.

Example fix

// before
var mat = modelComponent.GetMaterial(i - 1); // may pass -1
// after
if (i - 1 >= 0)
    var mat = modelComponent.GetMaterial(i - 1);
Defensive patterns

Strategy: validation

Validate before calling

if (index < 0) return null; // or clamp: index = Math.Max(0, index);

Type guard

Material SafeGetMaterial(ModelComponent mc, int i) => i < 0 ? null : mc.GetMaterial(i);

Try / catch

try { m = mc.GetMaterial(i); }
catch (ArgumentOutOfRangeException) { m = null; }

Prevention

When it happens

Trigger: Calling GetMaterial(-1) or with a negative computed index (e.g. loop arithmetic going below zero).

Common situations: Loop code computing index from an offset that can be negative; searching a collection backwards and passing -1 sentinel to GetMaterial.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Engine/Engine/ModelComponent.cs:176

        /// <value>The bounding box.</value>
        [DataMemberIgnore]
        public BoundingBox BoundingBox;

        /// <summary>
        /// Gets the bounding sphere in world space.
        /// </summary>
        /// <value>The bounding sphere.</value>
        [DataMemberIgnore]
        public BoundingSphere BoundingSphere;

        /// <summary>
        /// Gets the material at the specified index. If the material is not overriden by this component, it will try to get it from <see cref="Stride.Rendering.Model.Materials"/>
        /// </summary>
        /// <param name="index">The index of the material</param>
        /// <returns>The material at the specified index or null if not found</returns>
        public Material GetMaterial(int index)
        {
            if (index < 0) throw new ArgumentOutOfRangeException(nameof(index), @"index cannot be < 0");

            Material material;
            if (Materials.TryGetValue(index, out material))
            {
                return material;
            }
            // TODO: if Model is null, shouldn't we always return null?
            if (Model != null && index < Model.Materials.Count)
            {
                material = Model.Materials[index].Material;
            }
            return material;
        }

        /// <summary>
        /// Gets the number of materials (computed from <see cref="Stride.Rendering.Model.Materials"/>)
        /// </summary>
        /// <returns></returns>

View on GitHub (pinned to 96fad776d2)