dotnet/wpf · error · InvalidOperationException

SR.ExpectedBinaryContent

Error message

SR.ExpectedBinaryContent

What it means

ConvertFrom expects the incoming value to be deferred content binary data: either a Stream or a byte[] (which it wraps in a MemoryStream). If the value is neither, it throws InvalidOperationException(SR.ExpectedBinaryContent) because no binary content can be deferred.

Solutions

  1. Pass the raw BAML Stream (from Application resource stream, e.g. Application.GetResourceStream) to the converter
  2. If you have byte[], pass the array directly — it is wrapped in a MemoryStream internally
  3. Do not pass XAML text/strings; recompile the XAML to BAML or use XamlReader for text-based XAML

Example fix

// before
converter.ConvertFrom(null, CultureInfo.InvariantCulture, xamlText);
// after
using (var stream = Application.GetResourceStream(new Uri("mydict.xaml", UriKind.Relative)).Stream)
    converter.ConvertFrom(null, CultureInfo.InvariantCulture, stream);
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is not Stream and not byte[])
    throw new ArgumentException("Deferrable content must be a Stream or byte[].");

Type guard

static bool IsDeferredBinaryContent(object v) => v is Stream or byte[];

Try / catch

try { return (DeferrableContent)converter.ConvertFrom(ctx, culture, value); }
catch (InvalidOperationException ex) when (ex.Message.Contains("binary")) { /* convert/compile to BAML first */ }

Prevention

When it happens

Trigger: Passing ConvertFrom a value that is not a Stream or byte[] — for example a string of XAML, an XmlReader, or null — while the schema context and target dictionary checks already passed.

Common situations: Hand-rolling deferred-content conversion from raw XAML text instead of the compiled BAML stream, deserializing an old/persisted resource format where content was stored as text, or a loader pipeline that decoded the BAML into a different representation.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/DeferrableContentConverter.cs:63

                ResourceDictionary dictionary = ipvt.TargetObject as ResourceDictionary;
                if (dictionary == null)
                {
                    throw new InvalidOperationException(SR.ExpectedResourceDictionaryTarget);
                }

                Stream stream = value as Stream;
                if (stream == null)
                {
                    byte[] bytes = value as byte[];
                    if (bytes != null)
                    {
                        stream = new MemoryStream(bytes);
                    }
                }
                if (stream == null)
                {
                    throw new InvalidOperationException(SR.ExpectedBinaryContent);
                }

                // we shouldn't pass around the service provider
                DeferrableContent deferrableContext = new DeferrableContent(stream, schemaContext,
                    objectWriterFactory, context, rootObjectProvider.RootObject);
                return deferrableContext;
            }

            return base.ConvertFrom(context, culture, value);
        }

        private static T RequireService<T>(IServiceProvider provider) where T : class
        {
            T result = provider.GetService(typeof(T)) as T;
            if (result == null)
            {
                throw new InvalidOperationException(SR.Format(SR.DeferringLoaderNoContext, nameof(DeferrableContentConverter), typeof(T).Name));
            }

View on GitHub (pinned to 81131a70a4)