dotnet/wpf · error · InvalidOperationException
SR.Timing_AccelAndDecelGreaterThanOne
Error message
SR.Timing_AccelAndDecelGreaterThanOne
What it means
Timeline.ValidateTimeline (invoked when the timeline is frozen via FreezeCore) enforces the invariant AccelerationRatio + DecelerationRatio <= 1; exceeding it throws InvalidOperationException with Timing_AccelAndDecelGreaterThanOne. The timing engine cannot both accelerate and decelerate for more than 100% of the duration, so the freeze fails.
Solutions
- Ensure AccelerationRatio + DecelerationRatio <= 1 before freezing; scale both down proportionally if needed.
- Freeze manually at a point you control so you get the error early with a clear stack.
- If ratios come from config, validate the pair together, not individually.
Example fix
// before anim.AccelerationRatio = 0.7; anim.DecelerationRatio = 0.5; // sum 1.2 // after double a = 0.7, d = 0.5; double scale = a + d > 1.0 ? 1.0 / (a + d) : 1.0; anim.AccelerationRatio = a * scale; anim.DecelerationRatio = d * scale;
Defensive patterns
Strategy: validation
Validate before calling
if (a + d > 1.0) { double s = 1.0 / (a + d); a *= s; d *= s; }
anim.AccelerationRatio = a; anim.DecelerationRatio = d;
anim.Freeze(); Type guard
static bool AreValidRatios(double a, double d) => a >= 0 && a <= 1 && d >= 0 && d <= 1 && a + d <= 1;
Try / catch
try { anim.Freeze(); }
catch (InvalidOperationException) { /* rescale ratios and refreeze */ } Prevention
- Validate AccelerationRatio and DecelerationRatio as a pair, not individually.
- Rescale proportionally whenever the sum exceeds 1.
- Freeze timelines early in a controlled place so violations surface with clear context.
When it happens
Trigger: Setting AccelerationRatio = 0.7 and DecelerationRatio = 0.5 (sum 1.2) and then calling timeline.Freeze() — or implicitly when WPF freezes the timeline (e.g., assigning it to a style/resource used from multiple threads). Individually valid values can still sum > 1.
Common situations: Tuning both ratios independently in XAML where each stays <= 1 but the sum exceeds 1; copying ratios from two different animations; animation templates whose combined defaults sum above 1.
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
- Animation_Invalid_DefaultValue
- SR.Animation_Invalid_DefaultValue
- SR.Animation_NoTextChildren
- SR.Animation_NoTextChildren
- SR.Animation_NoTextChildren
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/e2cf0922dc602748.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/Timeline.cs:720
}
/// <summary>
/// This method will throw an exception if a timeline has been incorrectly
/// constructed. Currently we validate all possible values when they are
/// set, but it is not possible to do this for Acceleration/DecelerationRatio.
///
/// The reason is when a timeline is instantiated in xaml the properties are
/// set with direct calls to DependencyObject.SetValue. This means our only
/// chance to validate the value is in the ValidateValue callback, which does
/// not allow querying of other DPs. Acceleration/DecelerationRatio are invalid
/// if their sum is > 1. This can't be verified in the ValidateValue callback,
/// so is done here.
/// </summary>
private void ValidateTimeline()
{
if (AccelerationRatio + DecelerationRatio > 1)
{
throw new InvalidOperationException(SR.Timing_AccelAndDecelGreaterThanOne);
}
}
#endregion // Methods
#region Events
/// <summary>
/// Raised whenever the value of the CurrentStateInvalidated property changes.
/// </summary>
public event EventHandler CurrentStateInvalidated
{
add
{
AddEventHandler(CurrentStateInvalidatedKey, value);
}
remove
{View on GitHub (pinned to 81131a70a4)