stride3d/stride · error · ArgumentOutOfRangeException
's must be finite
Error message
{owner}'s {fieldName} must be finite What it means
ValidateRange(this SVector3, ...) is a guard extension that ensures a vector value handed to the physics engine contains only finite components (no NaN or +/-Infinity). Bepu physics cannot simulate non-finite numbers and would corrupt the broadphase/solver, so it throws ArgumentOutOfRangeException with owner and field name context.
Solutions
- Check float.IsFinite on each component before assigning, and fix the upstream computation producing NaN/Infinity.
- Clamp or substitute defaults for invalid values (e.g. Vector3.One) before passing to the physics property.
- Enable catching at the source: validate deserialized config/model data after load.
Example fix
// before box.Size = new Vector3(1f / zeroScale); // NaN // after var s = zeroScale == 0 ? 1f : zeroScale; box.Size = new Vector3(MathF.Max(1f / s, 1e-6f));
Defensive patterns
Strategy: validation
Validate before calling
bool IsFinite(SVector3 v) => float.IsFinite(v.X) && float.IsFinite(v.Y) && float.IsFinite(v.Z);
if (!IsFinite(value)) throw new ArgumentException("Vector must be finite before assignment"); Try / catch
try { vec.ValidateRange(this); property = vec; } catch (ArgumentOutOfRangeException ex) { log.Error($"NaN/Infinity in {ex.ParamName}", ex); } Prevention
- Guard divisions that produce vector components (scale, area)
- Validate mesh/config data for NaN at load time
- Sanitize computed values with float.IsFinite checks before physics assignment
When it happens
Trigger: Setting a collider/body vector property (e.g. size, scale, position offsets) to a value containing NaN or Infinity, often from a division by zero or a bad input file upstream.
Common situations: Computing mesh bounds from an empty mesh, dividing by zero scale, or loading model data where a dimension is 0 leading to NaN in derived quantities.
Related errors
- Url must be valid, assign null instead
- 's must be normalized
- 's must be finite and greater than zero
- The provided path is not a valid path name.
- Build manifest [ ] doesn't exist
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/7f04ce6ea03c2652.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.BepuPhysics/Stride.BepuPhysics/Definitions/BepuAndStrideExtensions.cs:42
public static SRigidPose ToStride(this BRigidPose pose) => Unsafe.As<BRigidPose, SRigidPose>(ref pose);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static BBodyVelocity ToBepu(this SBodyVelocity pose) => Unsafe.As<SBodyVelocity, BBodyVelocity>(ref pose);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SBodyVelocity ToStride(this BBodyVelocity pose) => Unsafe.As<BBodyVelocity, SBodyVelocity>(ref pose);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NVector3 ToNumeric(this SVector3 vec) => Unsafe.As<SVector3, NVector3>(ref vec);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SVector3 ToStride(this NVector3 vec) => Unsafe.As<NVector3, SVector3>(ref vec);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static NQuaternion ToNumeric(this SQuaternion qua) => Unsafe.As<SQuaternion, NQuaternion>(ref qua);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static SQuaternion ToStride(this NQuaternion qua) => Unsafe.As<NQuaternion, SQuaternion>(ref qua);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateRange<T>(this SVector3 vec, T owner, [CallerMemberName] string? fieldName = null)
{
if (NVector3.AllWhereAllBitsSet(NVector3.IsFinite(vec)) == false)
throw new ArgumentOutOfRangeException($"{owner}'s {fieldName} must be finite");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateRange<T>(this SQuaternion quat, T owner, [CallerMemberName] string? fieldName = null)
{
if (quat.IsNormalized == false)
throw new ArgumentOutOfRangeException($"{owner}'s {fieldName} must be normalized");
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ValidateGreaterThanZeroFinite<T>(this float fp, T owner, [CallerMemberName] string? fieldName = null)
{
if (fp <= 0 || float.IsFinite(fp) == false)
throw new ArgumentOutOfRangeException($"{owner}'s {fieldName} must be finite and greater than zero");
}
}
View on GitHub (pinned to 96fad776d2)