dotnet/wpf · error · AssemblyVersionParseException
SR.InvalidAssemblyVersion
Error message
SR.InvalidAssemblyVersion (InvalidAssemblyVersion: {AssemblyVersion}) What it means
CheckValue validates values passed into ConcurrentDictionary<K,V>; it throws ArgumentNullException with parameter name "value" when a null value is stored via the indexer or set path. This internal dictionary deliberately disallows null values because it uses null as the internal miss sentinel in the backing Hashtable.
Solutions
- Do not store null values; skip nulls or use a sentinel/wrapper (e.g. store a NullValue marker type).
- Check the value for null before assignment and handle the miss explicitly at the call site.
- If a null means 'not present', remove the key instead of assigning null (use the Remove member).
- If you need null values, wrap the value in a Nullable-style struct or Optional<T>.
Example fix
// before cache[key] = ComputeValue(); // throws when ComputeValue() returns null // after var v = ComputeValue(); if (v != null) cache[key] = v;
Defensive patterns
Strategy: validation
Validate before calling
if (value is null) throw new InvalidOperationException("Refusing to store null value in ConcurrentDictionary"); Type guard
static bool IsStorable<V>(V v) => v is not null;
Try / catch
try { dict[key] = value; } catch (ArgumentNullException ex) when (ex.ParamName == "value") { /* skip or substitute sentinel */ } Prevention
- Never assign null values into this dictionary
- Use a sentinel object or Optional<T> wrapper for 'missing' semantics
- Guard results of nullable-producing factories before caching
- Prefer removing the key over storing null
When it happens
Trigger: Calling dict[key] = null, or any ICollection<KeyValuePair<K,V>>/indexer set path whose value is null; CheckValue(result == null) throws immediately.
Common situations: Caching APIs that return null and whose result is stored directly into the dictionary; deserialization filling a dictionary with null entries; refactored code that previously used Dictionary<K,V>, which permits null values.
Related errors
- ArgumentException: path
- ArgumentException: relativeTo
- ArgumentNullException: path
- ArgumentNullException: relativeTo
- File name is null or empty.
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/abc0e5cae34a4772.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs:2645
// Generate canonicalized string as resource id.
bool requestExtensionChange = false;
string resourceID = ResourcesGenerator.GetResourceIdForResourceFile(
SourceFileInfo.RelativeSourceFilePath + XAML,
SourceFileInfo.OriginalFileLinkAlias,
SourceFileInfo.OriginalFileLogicalName,
TargetPath,
Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar,
requestExtensionChange);
string uriPart = string.Empty;
// Attempt to parse out the AssemblyVersion if it exists. This validates that we can either use an empty version string (wildcards exist)
// or we can utilize the passed in string (valid parse).
if (!VersionHelper.TryParseAssemblyVersion(AssemblyVersion, allowWildcard: true, version: out _, out bool hasWildcard)
&& !string.IsNullOrWhiteSpace(AssemblyVersion))
{
throw new AssemblyVersionParseException(SR.Format(SR.InvalidAssemblyVersion, AssemblyVersion));
}
// In .NET Framework (non-SDK-style projects), the process to use a wildcard AssemblyVersion is to do the following:
// - Modify the AssemblyVersionAttribute to a wildcard string (e.g. "1.2.*")
// - Set Deterministic to false in the build
// During MarkupCompilation, the AssemblyVersion property would not be set and WPF would correctly generate a resource URI without a version.
// In .NET Core/5 (or .NET Framework SDK-style projects), the same process can be used if GenerateAssemblyVersionAttribute is set to false in
// the build. However, this isn't really the idiomatic way to set the version for an assembly. Instead, developers are more likely to use the
// AssemblyVersion build property. If a developer explicitly sets the AssemblyVersion build property to a wildcard version string, we would use
// that as part of the URI here. This results in an error in Version.Parse during InitializeComponent's call tree. Instead, do as we would have
// when the developer sets a wildcard version string via AssemblyVersionAttribute and use an empty string.
string version = hasWildcard || String.IsNullOrEmpty(AssemblyVersion)
? String.Empty
: COMPONENT_DELIMITER + VER + AssemblyVersion;
string token = String.IsNullOrEmpty(AssemblyPublicKeyToken)
? String.Empty
: COMPONENT_DELIMITER + AssemblyPublicKeyToken;View on GitHub (pinned to 81131a70a4)