dotnet/wpf · error · ArgumentException

SR.UnknownReferenceSerialize

Error message

SR.UnknownReferenceSerialize

What it means

CompoundFileReference.Save serializes a reference (path into the compound file) and accepts only CompoundFileStreamReference or CompoundFileStorageReference. Passing any other CompoundFileReference-derived type raises ArgumentException(SR.UnknownReferenceSerialize, nameof(reference)) because the writer does not know how to encode its RefComponentType.

Solutions

  1. Pass only CompoundFileStreamReference or CompoundFileStorageReference instances to Save.
  2. If you added a custom reference type, extend the serialization logic to handle it (or convert it to a supported type first).
  3. Check where the reference object was created — a mis-mapped factory can yield the wrong subclass.
  4. Inspect reference.GetType() at the call site to identify the unexpected type.

Example fix

// before: saving a custom reference type
CompoundFileReference r = new MyCustomReference(path);
file.Save(r, writer);

// after: convert to a supported reference type
var r = new CompoundFileStorageReference(path);
file.Save(r, writer);
Defensive patterns

Strategy: type-guard

Validate before calling

bool IsSerializableReference(CompoundFileReference r) => r is CompoundFileStreamReference || r is CompoundFileStorageReference;

Type guard

bool IsStreamOrStorageRef(CompoundFileReference r) => r is CompoundFileStreamReference or CompoundFileStorageReference;

Try / catch

try { reference.Save(writer); } catch (ArgumentException ex) when (ex.ParamName == "reference") { ConvertToSupportedReferenceAndRetry(); }

Prevention

When it happens

Trigger: Calling Save (directly or via compound-file write paths) with a reference object that is neither a stream nor a storage reference — e.g. a custom subclass of CompoundFileReference or a wrong object passed where a reference was expected.

Common situations: Custom OPC/compound-file extensions adding new reference kinds without extending Save; refactoring that swapped in a different reference type; deserialization code creating a type Save doesn't recognize.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/CompoundFileReference.cs:105

        #region Persistence

        /// <summary>Save to a stream</summary>
        /// <param name="reference">reference to save</param>
        /// <param name="writer">The BinaryWriter to persist this object to.  
        /// This method will alter the stream pointer of the underlying stream as a side effect.
        /// Passing null simply calculates how many bytes would be written.</param>
        /// <returns>number of bytes written including any padding</returns>
        internal static int Save(CompoundFileReference reference, BinaryWriter writer)
        {
            int bytes = 0;

            // NOTE: Our RefComponentType must be written by our caller
            bool calcOnly = (writer == null);

            // what are we dealing with here?
            CompoundFileStreamReference streamReference = reference as CompoundFileStreamReference;
            if ((streamReference == null) && (!(reference is CompoundFileStorageReference)))
                throw new ArgumentException(SR.UnknownReferenceSerialize, nameof(reference));

            // first parse the path into strings
            string[] segments = ContainerUtilities.ConvertBackSlashPathToStringArrayPath(reference.FullName);
            int entries = segments.Length;

            // write the count
            if (!calcOnly)
                writer.Write( entries );

            bytes += ContainerUtilities.Int32Size;

            // write the segments - if we are dealing with a stream entry, don't write the last "segment"
            // because it is in fact a stream name
            for (int i = 0; i < segments.Length - (streamReference == null ? 0 : 1); i++)
            {
                if (!calcOnly)
                {
                    writer.Write( (Int32)RefComponentType.Storage );

View on GitHub (pinned to 81131a70a4)