stride3d/stride · error · IndexOutOfRangeException
'm' parameter should be between '-l' and '+l'.
Error message
'm' parameter should be between '-l' and '+l'.
What it means
SphericalHarmonics.CheckIndicesValidity validates the (l, m) indices used to address a spherical harmonic basis function. For a given degree l, the order m must satisfy |m| <= l; otherwise the index pair does not identify a valid harmonic. The library throws IndexOutOfRangeException with this message when Math.Abs(m) > l.
Solutions
- Clamp or validate m so that -l <= m <= l before calling the API.
- Fix loop bounds: iterate m from -l to l (inclusive) per degree l, not over a fixed range.
- Verify the l/m argument order was not swapped at the call site (a common convention mistake).
- Use LmToCoefficientIndex(l, m) consistently so coefficient indexing matches the validated (l, m) pairs.
Example fix
// before
sh.SetCoefficient(1, 2, value); // l=1, m=2 -> |m| > l
// after
int l = 1, m = 1;
if (Math.Abs(m) <= l)
sh.SetCoefficient(l, m, value); Defensive patterns
Strategy: validation
Validate before calling
int l = /* desired degree */, m = /* desired order */;
int maxOrder = 2; // library maxOrder, adjust per usage
if (l < 0 || l > maxOrder - 1)
throw new ArgumentOutOfRangeException(nameof(l), $"'l' must be between 0 and {maxOrder - 1}.");
if (Math.Abs(m) > l)
throw new ArgumentOutOfRangeException(nameof(m), $"'m' must be between -l and +l for l={l}."); Try / catch
try
{
sh.SetValue(l, m, value);
}
catch (IndexOutOfRangeException ex)
{
// invalid (l, m) pair — clamp m to [-l, l] and retry or log
int clamped = Math.Clamp(m, -l, l);
sh.SetValue(l, clamped, value);
} Prevention
- Iterate m from -l to l for each degree l, never over a fixed range.
- Double-check l/m argument order against the library convention.
- Add an assertion |m| <= l in harmonic coefficient loops.
When it happens
Trigger: Calling SphericalHarmonics evaluation/constructor helpers (e.g. SphericalHarmonics.FromBasicTerms / Evaluate-style APIs) with an (l, m) pair where l is within maxOrder-1 but m is outside [-l, +l], such as l=1 with m=2 or l=0 with m=-1.
Common situations: Hand-rolling loops over harmonic coefficients with wrong bounds (iterating m over the full order range instead of -l..l); porting shader or physics code that uses a different (m, l) convention; hardcoding indices without the |m|<=l constraint.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Indices for ColorBGRA run from 0 to 3, inclusive.
- There must be three and only three input values for Double3.
- The destination array must be of same length or larger…
- There must be four and only four input values for Double4.
- The destination array must be of same length or larger…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/10a5189e2f399bd3.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Mathematics/SphericalHarmonics.cs:101
CheckIndicesValidity(l, m, order);
return Coefficients[LmToCoefficientIndex(l, m)];
}
set
{
CheckIndicesValidity(l, m, order);
Coefficients[LmToCoefficientIndex(l, m)] = value;
}
}
// ReSharper disable UnusedParameter.Local
private static void CheckIndicesValidity(int l, int m, int maxOrder)
// ReSharper restore UnusedParameter.Local
{
if (l > maxOrder - 1)
throw new IndexOutOfRangeException("'l' parameter should be between '0' and '{0}' (order-1).".ToFormat(maxOrder - 1));
if (Math.Abs(m) > l)
throw new IndexOutOfRangeException("'m' parameter should be between '-l' and '+l'.");
}
private static int LmToCoefficientIndex(int l, int m)
{
return l * l + l + m;
}
}
/// <summary>
/// A spherical harmonics representation of a cubemap.
/// </summary>
[DataContract("SphericalHarmonics")]
public class SphericalHarmonics : SphericalHarmonics<Color3>
{
private readonly float[] baseValues;
private const float Pi4 = 4 * MathUtil.Pi;
private const float Pi16 = 16 * MathUtil.Pi;View on GitHub (pinned to 96fad776d2)