stride3d/stride · error · ArgumentOutOfRangeException

The destination array must be of same length or larger lengt

Error message

The destination array must be of same length or larger length than the source array.

What it means

ShapeCacheSystem.GetClosestToDecomposableScale uses a local Orthogonalize helper (a zero-allocation dump of Stride's Vector3.Orthogonalize) which requires the destination span to be at least as long as the source span. When the caller supplies a smaller destination buffer, the method throws ArgumentOutOfRangeException naming 'destination'. This mirrors the standard contract of the original vector-math API it replaces.

Solutions

  1. Allocate or stackalloc the destination span with length >= source.Length before calling
  2. Size scratch buffers from the actual point count of the shape rather than a fixed constant
  3. Add an explicit destination.Length >= source.Length check at the call site with a fallback path
  4. If using fixed buffers, cap/reject source data that exceeds the buffer capacity instead of letting it throw

Example fix

// before
Span<Vector3> dest = stackalloc Vector3[8];
Orthogonalize(source, dest); // throws if source.Length > 8
// after
Span<Vector3> dest = source.Length <= 8 ? stackalloc Vector3[8] : new Vector3[source.Length];
Orthogonalize(source, dest);
Defensive patterns

Strategy: validation

Validate before calling

if (destination.Length < source.Length)
    destination = new Vector3[source.Length]; // or resize before calling

Try / catch

try { result = GetClosestToDecomposableScale(...); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "destination") { /* grow buffer and retry */ }

Prevention

When it happens

Trigger: Calling GetClosestToDecomposableScale with shape vertex/point data whose buffer count exceeds the scratch span passed as 'destination' — e.g. a fixed-size stackalloc buffer used with a larger source array.

Common situations: Scale-conversion code for convex shapes where the number of points varies (convex hulls with more vertices than the preallocated span); buffer sized for one shape type reused for a bigger shape after a mesh/hull change.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/Systems/ShapeCacheSystem.cs:300

            Orthogonalize(basisIn, basisOut);
            o.X = basisOut[0].Length();
            o.Y = basisOut[1].Length();
            o.Z = basisOut[2].Length();
        }
        else
        {
            o.X = matrix.Row1.Length();
            o.Y = matrix.Row2.Length();
            o.Z = matrix.Row3.Length();
        }

        return o;

        static void Orthogonalize(ReadOnlySpan<Vector3> source, Span<Vector3> destination)
        {
            // Dump of strides' method to strip the memory alloc, refer to Vector3.Orthogonalize
            if (destination.Length < source.Length)
                throw new ArgumentOutOfRangeException(nameof(destination), "The destination array must be of same length or larger length than the source array.");

            for (int i = 0; i < source.Length; ++i)
            {
                Vector3 newVector = source[i];

                for (int r = 0; r < i; ++r)
                {
                    newVector -= (Vector3.Dot(destination[r], newVector) / Vector3.Dot(destination[r], destination[r])) * destination[r];
                }

                destination[i] = newVector;
            }
        }
    }

    /// <summary>
    /// Hold onto this to keep the cache and the bepu shape for the corresponding mesh alive
    /// </summary>

View on GitHub (pinned to 96fad776d2)