You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
YAML provider returns null for a document containing any property the target type lacks, so removing a property orphans every saved YAML record #88
YamlSerializationProvider builds its deserializer without IgnoreUnmatchedProperties() (Essentials.SerializationProviders.Yaml/YamlSerializationProvider.cs:22-25):
private readonly IDeserializer deserializer = new DeserializerBuilder()
.WithNamingConvention(CamelCaseNamingConvention.Instance)
.Build();
YamlDotNet throws YamlException ("Property 'x' not found on type ...") for any mapping key that has no matching member. Deserialize<T> catches that exception at L81-L84 and returns default. The two JSON providers accept the same document and ignore the extra member, so ISerializationProvider behaves differently depending on the implementation behind it.
Failure scenario
Serialize V1 { Value = 42, Legacy = "x" }, then deserialize the result as V2 { Value }, i.e. the same type after Legacy was removed:
Provider
Text
Deserialize<V2>
Yaml
value: 42\nlegacy: x\n
null
Json (System.Text.Json)
{"Value":42,"Legacy":"x"}
Value = 42
NewtonsoftJson
{"Value":42,"Legacy":"x"}
Value = 42
Removing or renaming a property is ordinary schema evolution. With YAML-backed persistence, every record written before that change now reads back as missing. The caller gets no error, because the exception is swallowed. Combined with RetrieveOrCreateAsync, the file is then overwritten with new T() (#82), so the user's other settings are destroyed too. #82 covers the overwrite. This issue covers why a well-formed, valid document is treated as unreadable in the first place.
Suggested fix
Add .IgnoreUnmatchedProperties() to the DeserializerBuilder, matching the JSON providers' default.
Acceptance criteria
A test: a YAML document with an extra key deserializes into the narrower type with the known members populated.
Area / suggested assignment:Essentials.SerializationProviders.Yaml. The suggested contract test across all ISerializationProvider implementations belongs in the shared serialization tests.
Activity
matt-edmondson commentedon Oct 6, 2026
Triage
nullwith no error. ThroughRetrieveOrCreateAsync(RetrieveOrCreateAsync overwrites a stored file it cannot parse with new T(), destroying the user's data #82), those records are then overwritten withnew T(), so user data is destroyed. The fix is a one-line.IgnoreUnmatchedProperties().Essentials.SerializationProviders.Yaml. The suggested contract test across allISerializationProviderimplementations belongs in the shared serialization tests.Generated by Claude Code