dotnet/wpf · error · InvalidOperationException

SR.ShareableExpressionsCannotChangeSources

Error message

SR.ShareableExpressionsCannotChangeSources

What it means

Expression.ChangeSources updates the list of DependencyObjects the expression depends on, but a shareable expression (e.g. a shared StaticResource-style expression) is immutable with respect to its sources. If the expression is marked Shareable, ChangeSources throws InvalidOperationException(SR.ShareableExpressionsCannotChangeSources) because mutating shared expressions would affect every consumer.

Solutions

  1. Construct the expression without the Shareable ExpressionMode if its sources need to change over time
  2. Create a new expression instance per target instead of sharing one instance
  3. Re-evaluate/replace the whole expression (e.g. re-apply the markup extension) rather than mutating sources
  4. Split logic: use a shareable immutable expression for static cases and a non-shareable one for dynamic cases

Example fix

// before
var expr = new ObjectRefExpression(obj, prop, ExpressionMode.Shareable);
expr.ChangeSources(target, newSources); // throws
// after
var expr = new ObjectRefExpression(obj, prop, ExpressionMode.None);
expr.ChangeSources(target, newSources); // ok
Defensive patterns

Strategy: type-guard

Validate before calling

if (expression is { Shareable: true }) throw new NotSupportedException("Cannot change sources of a shareable expression");

Type guard

static bool CanChangeSources(System.Windows.Expression e) => !e.Shareable;

Try / catch

try { expr.ChangeSources(d, newSources); }
catch (InvalidOperationException ex) when (expr.Shareable) { log.Warn("Shareable expression is immutable; recreating", ex); }

Prevention

When it happens

Trigger: Calling ChangeSources (directly or via DependencyObject expression invalidation plumbing) on an expression constructed with ExpressionMode.Shareable after it has been attached and used.

Common situations: Custom markup extensions or expression subclasses that start sharing instances (shareable mode) but then attempt dynamic source changes; reusing one expression instance across multiple dependency properties while its sources evolve.

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/e0266cbc134f0d5f. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Expression.cs:207

        /// </summary>
        /// <remarks>
        ///     Expression must be in use on provided DependencyObject/DependencyProperty.
        ///     GetSources must reflect the old sources to be replaced by the provided newSources.
        /// </remarks>
        /// <param name="d">DependencyObject whose sources are to be updated</param>
        /// <param name="dp">The property that the Expression is set to</param>
        /// <param name="newSources">New sources</param>
        internal void ChangeSources(DependencyObject d, DependencyProperty dp, DependencySource[] newSources)
        {
            if (!ForwardsInvalidations)
            {
                ArgumentNullException.ThrowIfNull(d);
                ArgumentNullException.ThrowIfNull(dp);
            }

            if (Shareable)
            {
                throw new InvalidOperationException(SR.ShareableExpressionsCannotChangeSources);
            }

            DependencyObject.ValidateSources(d, newSources, this);

            // Additional validation in callee
            if (ForwardsInvalidations)
            {
                DependencyObject.ChangeExpressionSources(this, null, null, newSources);
            }
            else
            {
                DependencyObject.ChangeExpressionSources(this, d, dp, newSources);
            }
        }


        // Determines if Expression can be attached:
        //    1) If Shareable

View on GitHub (pinned to 81131a70a4)