dotnet/wpf · error · InvalidOperationException

SR.InvalidCustomSerialize

Error message

SR.InvalidCustomSerialize

What it means

XamlSerializer.ConvertStringToCustomBinary base implementation always throws InvalidOperationException(SR.InvalidCustomSerialize). It is the public entry for converting a string value into a compact binary form for BAML; the base throws, so any serializer without the override cannot perform custom string serialization.

Solutions

  1. Override ConvertStringToCustomBinary in the serializer to write the compact binary representation to the BinaryWriter.
  2. If custom binary conversion is not desired, remove the serializer registration so values serialize via the default path.
  3. Mirror-implement both directions (ConvertStringToCustomBinary and the matching read) to keep BAML round-trippable.

Example fix

// before
class MySerializer : XamlSerializer { }
// after
class MySerializer : XamlSerializer {
    public override bool ConvertStringToCustomBinary(BinaryWriter writer, string stringValue) {
        writer.Write(stringValue); // implement real compact encoding
        return true;
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

var m = serializer.GetType().GetMethod("ConvertStringToCustomBinary", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
bool canWrite = m != null && m.DeclaringType != typeof(XamlSerializer);

Type guard

static bool SupportsCustomBinaryWrite(XamlSerializer s) => s.GetType().GetMethod("ConvertStringToCustomBinary", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic)!.DeclaringType != typeof(XamlSerializer);

Try / catch

try { ok = serializer.ConvertStringToCustomBinary(writer, value); } catch (InvalidOperationException ex) when (ex.Message.Contains("CustomSerialize")) { log.Error($"{serializer.GetType().Name} cannot write custom binary; falling back to string record"); // fallback: write as plain string record
}

Prevention

When it happens

Trigger: BAML writing (BamlRecordWriter.WriteRecordData) encounters a value whose serializer must convert a string to custom binary, but the serializer subclass did not override ConvertStringToCustomBinary.

Common situations: Registering a ValueSerializer/XamlSerializer for a type to speed up BAML but only implementing the deserialize (binary->object) side; compiler/optimizer pipelines that write strings without the corresponding override.

Understand the failure class

Background: "NotImplementedError: Subclasses should override this method" / "must be implemented" — abstract method errors explained — this error's family across 40 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Markup/XamlSerializer.cs:100

        internal virtual void ConvertBamlToObject (
            BamlRecordReader    reader,       // Current reader that is processing records
            BamlRecord          bamlRecord,   // Record read in that triggered serializer
            ParserContext       context)      // Context
        {
            throw new InvalidOperationException(SR.InvalidDeSerialize);
        }

#endif

        /// <summary>
        ///   Convert a string into a compact binary representation and write it out
        ///   to the passed BinaryWriter.
        /// </summary>
        public virtual bool ConvertStringToCustomBinary (
            BinaryWriter   writer,           // Writer into the baml stream
            string         stringValue)      // String to convert
        {
            throw new InvalidOperationException(SR.InvalidCustomSerialize);
        }
        
        /// <summary>
        ///   Convert a compact binary representation of a certain object into and instance
        ///   of that object.  The reader must be left pointing immediately after the object 
        ///   data in the underlying stream.
        /// </summary>
        public virtual object ConvertCustomBinaryToObject(
            BinaryReader reader)
        {
            throw new InvalidOperationException(SR.InvalidCustomSerialize);
        }            

        /// <summary>
        ///   If the object created by this serializer is stored in a dictionary, this
        ///   method will extract the key used for this dictionary from the passed 
        ///   collection of baml records.  How the key is determined is up to the
        ///   individual serializer.  By default, there is no key retrieved.

View on GitHub (pinned to 81131a70a4)