stride3d/stride · error · InvalidOperationException
Direction is in neutral position
Error message
Direction is in neutral position
What it means
Direction.GetTicks converts the current direction into ticks on a circular scale. If the underlying value is null — the direction is in its neutral/rest position with no deflection — it throws InvalidOperationException because there is no rotation to convert.
Solutions
- Check whether the direction has a value before calling GetTicks (e.g. inspect HasValue/neutral state)
- Skip tick computation when the input is neutral and treat it as 0 in caller logic
- Use the gamepad's axis/index values instead when neutral readings matter
Example fix
// before int ticks = direction.GetTicks(maxValue); // after int ticks = direction.HasValue ? direction.GetTicks(maxValue) : 0;
Defensive patterns
Strategy: validation
Validate before calling
if (!direction.HasValue) return 0; int ticks = direction.GetTicks(maxValue);
Type guard
bool IsActive(Direction d) => d.HasValue;
Try / catch
try { ticks = direction.GetTicks(maxValue); }
catch (InvalidOperationException) { ticks = 0; } Prevention
- Treat neutral position as 0 ticks in input aggregation
- Check input state before first use each frame
- Cache whether the device has ever reported a non-neutral value
When it happens
Trigger: Calling GetTicks on a Direction instance whose backing value has not been set (e.g. a gamepad stick or trigger at rest, or a Direction created but never updated) before reading tick values.
Common situations: Polling a gamepad's virtual 'Direction' property on the first frame before any input event; reading rotation ticks for a device returning neutral position (stick centered).
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- ActivatedGestures collection was modified but the action…
- Tried to modify the configuration after is has been frozen.
- value
- value
- value
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/a1e04265e76e0c54.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Input/Direction.cs:64
/// with 0/1 corresponding to the direction (0,1), 1/4 corresponding to (1,0), etc.
/// </summary>
/// <param name="value">The amount of ticks clockwise from the Up direction (numerator)</param>
/// <param name="maxValue">The number of ticks representing a full rotation (denominator)</param>
/// <returns>A direction with ratio <paramref name="value"/> over <paramref name="maxValue"/></returns>
public static Direction FromTicks(int value, int maxValue)
{
return new Direction((int)(MaxValue / maxValue * value));
}
/// <summary>
/// Retrieves the amount of ticks clockwise from the Up direction
/// </summary>
/// <param name="maxValue">The number of ticks representing a full rotation</param>
/// <returns></returns>
public int GetTicks(int maxValue)
{
if (!value.HasValue)
throw new InvalidOperationException("Direction is in neutral position");
if (maxValue <= 0)
throw new ArgumentOutOfRangeException(nameof(maxValue));
return (int)Math.Round(value.Value / ((double)MaxValue / (uint)maxValue)) % maxValue;
}
public static explicit operator Vector2(Direction value)
{
if (!value.value.HasValue)
return Vector2.Zero;
return new Vector2
{
X = (float)Math.Sin(value.value.Value * FullAngleInverse),
Y = (float)Math.Cos(value.value.Value * FullAngleInverse),
};
}
View on GitHub (pinned to 96fad776d2)