dotnet/wpf · error · InvalidOperationException

Animation_NoTextChildren

Animation_NoTextChildren

Error message

SR.Animation_NoTextChildren (Animation_NoTextChildren)

What it means

ByteAnimationUsingKeyFrames.AddText unconditionally throws InvalidOperationException with SR.Animation_NoTextChildren because timelines/key-frame animations cannot accept text content. The base Timeline API surface requires this override, but the type provides no meaningful text-children behavior.

Solutions

  1. Remove all text (including stray characters) from inside the <ByteAnimationUsingKeyFrames> element in XAML
  2. Express values with child key-frame elements like <DiscreteByteKeyFrame Value="10" .../> instead of text
  3. In code, never call AddText; use animation.KeyFrames.Add(...)

Example fix

// before (XAML)
<ByteAnimationUsingKeyFrames>10, 20, 30</ByteAnimationUsingKeyFrames>
// after
<ByteAnimationUsingKeyFrames>
  <DiscreteByteKeyFrame Value="10" KeyTime="0:0:0"/>
  <DiscreteByteKeyFrame Value="20" KeyTime="0:0:1"/>
</ByteAnimationUsingKeyFrames>
Defensive patterns

Strategy: validation

Validate before calling

// XAML guard: ensure the element body contains no text nodes
// e.g. only whitespace/comments between <ByteAnimationUsingKeyFrames> and child key frames

Try / catch

try { adder.AddText(text); }
catch (InvalidOperationException) { /* timelines take no text: move values into key-frame children */ }

Prevention

When it happens

Trigger: Placing literal text between the tags of a ByteAnimationUsingKeyFrames element in XAML (e.g. <ByteAnimationUsingKeyFrames>some text</ByteAnimationUsingKeyFrames>), or calling AddText programmatically.

Common situations: Whitespace or stray characters inside the animation element in XAML, or accidental copy/paste of inner text into the animation tag.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/179206a628ff3f96. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/Generated/ByteAnimationUsingKeyFrames.cs:277

        /// WritePreamble() or WritePostscript().  It also doesn't throw an
        /// ArgumentNullException if the childText parameter is null.  These tasks
        /// are performed by the interface implementation.  Therefore, it's OK
        /// for a derived class to override this method and call the base
        /// class implementation only if they determine that it's the right
        /// course of action.  The derived class can rely on KeyFrameAnimation's
        /// implementation of IAddChild.AddChild or implement their own
        /// following the Freezable pattern since that would be a public
        /// method.
        /// </remarks>
        /// <param name="childText">A string representing the child text that
        /// should be added.  If this is a KeyFrameAnimation an exception will be
        /// thrown.</param>
        /// <exception cref="InvalidOperationException">Timelines have no way
        /// of adding text.</exception>
        [EditorBrowsable(EditorBrowsableState.Advanced)]
        protected virtual void AddText(string childText)
        {
            throw new InvalidOperationException(SR.Animation_NoTextChildren);
        }

        #endregion

        #region ByteAnimationBase

        /// <summary>
        /// Calculates the value this animation believes should be the current value for the property.
        /// </summary>
        /// <param name="defaultOriginValue">
        /// This value is the suggested origin value provided to the animation
        /// to be used if the animation does not have its own concept of a
        /// start value. If this animation is the first in a composition chain
        /// this value will be the snapshot value if one is available or the
        /// base property value if it is not; otherise this value will be the 
        /// value returned by the previous animation in the chain with an 
        /// animationClock that is not Stopped.
        /// </param>

View on GitHub (pinned to 81131a70a4)