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
- Pass only CompoundFileStreamReference or CompoundFileStorageReference instances to Save.
- If you added a custom reference type, extend the serialization logic to handle it (or convert it to a supported type first).
- Check where the reference object was created — a mis-mapped factory can yield the wrong subclass.
- 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
- Only pass CompoundFileStreamReference/CompoundFileStorageReference to Save
- Type-check reference objects before serialization
- Extend Save explicitly if you add custom reference subclasses
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
- ' ' ID is not a valid XSD ID.
- Feature ID string cannot have zero length.
- Object identifiers must be unique within the same signature.
- Specified object ID conflicts with predefined Package…
- Specified part to sign does not exist.
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)