{"record":{"id":"bc9bcdde6b104b29","repo":"dotnet/wpf","slug":"animation-returnedunsetvalueinstance","errorCode":"Animation_ReturnedUnsetValueInstance","errorMessage":"SR.Animation_ReturnedUnsetValueInstance (Animation_ReturnedUnsetValueInstance)","messagePattern":"SR\\.Animation_ReturnedUnsetValueInstance \\(Animation_ReturnedUnsetValueInstance\\)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/AnimationStorage.cs","lineNumber":985,"sourceCode":"                    currentLayerValue = storage._snapshotValue;\n                }\n\n                Debug.Assert(clocksCount > 0);\n                Debug.Assert(defaultDestinationValue != DependencyProperty.UnsetValue);\n\n                for (int i = 0; i < clocksCount; i++)\n                {\n                    if (clocks[i].CurrentState != ClockState.Stopped)\n                    {\n                        hasActiveOrFillingClock = true;\n\n                        currentLayerValue = clocks[i].GetCurrentValue(currentLayerValue, defaultDestinationValue);\n\n                        // An animation may not return DependencyProperty.UnsetValue as its\n                        // current value.\n                        if (currentLayerValue == DependencyProperty.UnsetValue)\n                        {\n                            throw new InvalidOperationException(SR.Format(\n                                SR.Animation_ReturnedUnsetValueInstance,\n                                clocks[i].Timeline.GetType().FullName,\n                                dp.Name,\n                                d.GetType().FullName));\n                        }\n                    }\n                }\n\n                // The currentLayerValue only applies when there is at least one\n                // active or filling clock.\n                if (hasActiveOrFillingClock)\n                {\n                    currentPropertyValue = currentLayerValue;\n                }\n            }\n\n            // We have a calculated currentPropertyValue, so return it if the type matches.\n            if (DependencyProperty.IsValidType(currentPropertyValue, dp.PropertyType))","sourceCodeStart":967,"sourceCodeEnd":1003,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/AnimationStorage.cs#L967-L1003","documentation":"A custom AnimationClock's GetCurrentValue returned DependencyProperty.UnsetValue, which is reserved for the property system and never a legal animated value. WPF throws InvalidOperationException naming the timeline type, property, and owner type.","triggerScenarios":"A custom AnimationTimeline/animation clock returning UnsetValue from GetCurrentValue; misuse of UnsetValue as a sentinel in animation layering code.","commonSituations":"Custom animations that try to signal 'no value' by returning UnsetValue instead of the base value.","solutions":["Return the incoming baseValue (or a valid default) instead of UnsetValue when the animation has no value to contribute","Remove sentinel checks that leak UnsetValue out of GetCurrentValue","Add unit tests for the custom clock covering the 'nothing to apply' path"],"exampleFix":"// before\npublic override object GetCurrentValue(object baseValue, object d) => DependencyProperty.UnsetValue; // throws\n// after\npublic override object GetCurrentValue(object baseValue, object d) => baseValue;","handlingStrategy":"validation","validationCode":"object result = clock.GetCurrentValue(baseValue, dest);\nif (result == DependencyProperty.UnsetValue) result = baseValue;","typeGuard":"static bool IsValidReturnValue(object v) => v != DependencyProperty.UnsetValue;","tryCatchPattern":null,"preventionTips":["Never return UnsetValue from GetCurrentValue; return baseValue instead","Reserve UnsetValue for property-system metadata only"],"tags":["wpf","animation","unsetvalue","custom-animation"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}