Skip to content

Fix NullReferenceException when serializing null System.Type properties#1091

Merged
EdwardCooke merged 1 commit intoaaubry:masterfrom
fdcastel:fix/null-type-serialization
Apr 9, 2026
Merged

Fix NullReferenceException when serializing null System.Type properties#1091
EdwardCooke merged 1 commit intoaaubry:masterfrom
fdcastel:fix/null-type-serialization

Conversation

@fdcastel
Copy link
Copy Markdown
Contributor

Problem

Serializing an object with a System.Type property set to null throws a NullReferenceException. This was reported via a failing test in PR #1038.

Reproduction:

var serializer = new SerializerBuilder().Build();
var yaml = serializer.Serialize(new { MyType = (Type)null });
// throws NullReferenceException

Root Cause

SystemTypeConverter.WriteYaml() unconditionally casts value to Type and dereferences it without a null check:

var systemType = (Type)value!;  // NullReferenceException when value is null
emitter.Emit(new Scalar(..., systemType.AssemblyQualifiedName!, ...));

Since System.Type is a reference type (unlike value-type converters such as GuidConverter), it can legitimately be null. The null isn't caught by the normal pipeline because CustomSerializationObjectGraphVisitor.Enter() calls WriteYaml() immediately upon finding the converter, before the null-handling path in FullObjectGraphTraversalStrategy gets a chance to intercept.

Fix

  • WriteYaml: Added a null check — emits an empty scalar for null values instead of crashing.
  • ReadYaml: Added handling for empty scalars — returns null instead of passing an empty string to Type.GetType() which would throw.

Tests Added

Test Description
CanSerializeNullType Serializing a null Type property produces valid YAML
CanSerializeNonNullType Serializing a non-null Type property still works correctly
NullTypeRoundTrips Null Type survives serialize → deserialize round-trip
NonNullTypeRoundTrips Non-null Type survives serialize → deserialize round-trip

All 4 tests pass on net47, net6.0, and net8.0.

Closes #1038

SystemTypeConverter.WriteYaml() now handles null values by emitting an
empty scalar instead of crashing with NullReferenceException.

SystemTypeConverter.ReadYaml() now handles empty/null scalar values by
returning null instead of throwing on Type.GetType().

Added tests: CanSerializeNullType, CanSerializeNonNullType,
NullTypeRoundTrips, NonNullTypeRoundTrips.

Fixes the issue reported in PR aaubry#1038.
fdcastel added a commit to fdcastel/YamlDotNet that referenced this pull request Mar 26, 2026
All value-type converters (Guid, TimeSpan, DateTime, DateTimeOffset,
DateOnly, TimeOnly) now accept their Nullable<T> counterpart.

All converters (including reference-type Uri) now handle null values
in ReadYaml (return null for empty/null scalars) and WriteYaml (emit
an empty scalar instead of throwing NullReferenceException).

SystemTypeConverter is intentionally excluded — it is already fixed
by PR aaubry#1091.
fdcastel added a commit to fdcastel/YamlDotNet that referenced this pull request Mar 26, 2026
All value-type converters (Guid, TimeSpan, DateTime, DateTimeOffset,
DateOnly, TimeOnly) now accept their Nullable<T> counterpart.

All converters (including reference-type Uri) now handle null values
in ReadYaml (return null for empty/null scalars) and WriteYaml (emit
an empty scalar instead of throwing NullReferenceException).

SystemTypeConverter is intentionally excluded — it is already fixed
by PR aaubry#1091.
fdcastel added a commit to fdcastel/YamlDotNet that referenced this pull request Mar 28, 2026
All value-type converters (Guid, TimeSpan, DateTime, DateTimeOffset,
DateOnly, TimeOnly) now accept their Nullable<T> counterpart.

All converters (including reference-type Uri) now handle null values
in ReadYaml (return null for empty/null scalars) and WriteYaml (emit
an empty scalar instead of throwing NullReferenceException).

SystemTypeConverter is intentionally excluded — it is already fixed
by PR aaubry#1091.
@EdwardCooke EdwardCooke merged commit abc49b7 into aaubry:master Apr 9, 2026
1 check passed
This was referenced Apr 9, 2026
This was referenced Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants