dotnet/wpf · error · InvalidOperationException
SR.WhiteSpaceInCollection (deferredValue…
Error message
SR.WhiteSpaceInCollection (deferredValue, containingXamlType.Name)
What it means
In the deferred-value write path, a whitespace-only deferred string is rejected with InvalidOperationException naming the value and the containing XamlType, because the containing type is not a whitespace-significant collection. Same rule as the immediate WriteValue path, but applied to values buffered via writer.deferredValue.
Solutions
- Trim deferred values before they are buffered/flushed.
- Skip flushing values that are entirely whitespace when the containing type is not whitespace-significant.
- Add [WhitespaceSignificantCollection] to the containing collection type.
- Set xml:space="preserve" on the enclosing object so the significant-whitespace path is used.
Example fix
// before writer.deferredValue = raw; // may be " " // after writer.deferredValue = string.IsNullOrWhiteSpace(raw) ? null : raw.Trim();
Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrWhiteSpace(writer.deferredValue) && !GetContainingXamlType(writer).IsWhitespaceSignificantCollection) skipFlush = true;
Try / catch
try { FlushDeferred(writer); } catch (InvalidOperationException ex) when (ex.Message.Contains("whitespace")) { writer.deferredValue = null; } Prevention
- Normalize deferred values at capture time.
- Skip all-whitespace deferred values in non-significant collections.
- Mark custom collections with WhitespaceSignificantCollectionAttribute when needed.
When it happens
Trigger: Flush of a deferred value where writer.deferredValue is all whitespace and GetContainingXamlType(writer) yields a XamlType without WhitespaceSignificantCollectionAttribute — e.g. whitespace captured then flushed in a non-collection member context.
Common situations: Round-tripping pretty-printed XAML whose indentation was captured as deferred content, writing whitespace between items of ordinary List<T> properties, custom writers deferring values for batching then flushing.
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
- SR.WhiteSpaceInCollection (value, containingXamlType.Name)
- SR.FlowDocumentReaderCanHaveOnlyOneChild
- SR.FlowDocumentScrollViewerCanHaveOnlyOneChild
- SR.ObjectReaderInstanceDescriptorInvalidMethod
- SR.WhitespaceAfterME
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/bc115401d63c8bea.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/System.Xaml/System/Xaml/XamlXmlWriter.cs:1492
writer.currentState.WriteNamespace(writer, namespaceDeclaration);
}
public override void WriteEndMember(XamlXmlWriter writer)
{
if (writer.isFirstElementOfWhitespaceSignificantCollection)
{
WriteXmlSpace(writer);
writer.output.WriteValue(writer.deferredValue);
writer.currentState = InMemberAfterValue.State;
writer.currentState.WriteEndMember(writer);
writer.isFirstElementOfWhitespaceSignificantCollection = false;
}
else
{
XamlType containingXamlType = GetContainingXamlType(writer);
throw new InvalidOperationException(SR.Format(SR.WhiteSpaceInCollection, writer.deferredValue, containingXamlType.Name));
}
}
public override void WriteObject(XamlXmlWriter writer, XamlType type, bool isObjectFromMember)
{
writer.output.WriteValue(writer.deferredValue);
writer.currentState = InMemberAfterValue.State;
writer.currentState.WriteObject(writer, type, isObjectFromMember);
}
}
// Follows InObject after an End Object.
// Like InMember but also allows End Member.
//
private class InMemberAfterEndObject : WriterState
{
private static WriterState state = new InMemberAfterEndObject();View on GitHub (pinned to 81131a70a4)