{"record":{"id":"abc0e5cae34a4772","repo":"dotnet/wpf","slug":"sr-invalidassemblyversion-invalidassemblyversion","errorCode":null,"errorMessage":"SR.InvalidAssemblyVersion (InvalidAssemblyVersion: {AssemblyVersion})","messagePattern":"SR\\.InvalidAssemblyVersion \\(InvalidAssemblyVersion: (.+?)\\)","errorType":"validation","errorClass":"AssemblyVersionParseException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs","lineNumber":2645,"sourceCode":"\n            // Generate canonicalized string as resource id.\n            bool requestExtensionChange = false;\n            string resourceID = ResourcesGenerator.GetResourceIdForResourceFile(\n                    SourceFileInfo.RelativeSourceFilePath + XAML,\n                    SourceFileInfo.OriginalFileLinkAlias,\n                    SourceFileInfo.OriginalFileLogicalName,\n                    TargetPath,\n                    Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar,\n                    requestExtensionChange);\n\n            string uriPart = string.Empty;\n\n            // Attempt to parse out the AssemblyVersion if it exists.  This validates that we can either use an empty version string (wildcards exist)\n            // or we can utilize the passed in string (valid parse).\n            if (!VersionHelper.TryParseAssemblyVersion(AssemblyVersion, allowWildcard: true, version: out _, out bool hasWildcard)\n                && !string.IsNullOrWhiteSpace(AssemblyVersion))\n            {\n                throw new AssemblyVersionParseException(SR.Format(SR.InvalidAssemblyVersion, AssemblyVersion));\n            }\n\n            // In .NET Framework (non-SDK-style projects), the process to use a wildcard AssemblyVersion is to do the following:\n            //   - Modify the AssemblyVersionAttribute to a wildcard string (e.g. \"1.2.*\")\n            //   - Set Deterministic to false in the build\n            // During MarkupCompilation, the AssemblyVersion property would not be set and WPF would correctly generate a resource URI without a version.\n            // In .NET Core/5 (or .NET Framework SDK-style projects), the same process can be used if GenerateAssemblyVersionAttribute is set to false in\n            // 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\n            // AssemblyVersion build property.  If a developer explicitly sets the AssemblyVersion build property to a wildcard version string, we would use\n            // 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\n            // when the developer sets a wildcard version string via AssemblyVersionAttribute and use an empty string.\n            string version = hasWildcard || String.IsNullOrEmpty(AssemblyVersion)\n                ? String.Empty\n                : COMPONENT_DELIMITER + VER + AssemblyVersion;\n\n            string token = String.IsNullOrEmpty(AssemblyPublicKeyToken)\n                ? String.Empty\n                : COMPONENT_DELIMITER + AssemblyPublicKeyToken;","sourceCodeStart":2627,"sourceCodeEnd":2663,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/MarkupCompiler.cs#L2627-L2663","documentation":"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.","triggerScenarios":"Calling dict[key] = null, or any ICollection<KeyValuePair<K,V>>/indexer set path whose value is null; CheckValue(result == null) throws immediately.","commonSituations":"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.","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>."],"exampleFix":"// before\ncache[key] = ComputeValue(); // throws when ComputeValue() returns null\n// after\nvar v = ComputeValue();\nif (v != null) cache[key] = v;","handlingStrategy":"validation","validationCode":"if (value is null) throw new InvalidOperationException(\"Refusing to store null value in ConcurrentDictionary\");","typeGuard":"static bool IsStorable<V>(V v) => v is not null;","tryCatchPattern":"try { dict[key] = value; } catch (ArgumentNullException ex) when (ex.ParamName == \"value\") { /* skip or substitute sentinel */ }","preventionTips":["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"],"tags":["null","argument","dictionary","wpf","xaml"],"backgroundTag":"null-argument","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}