dotnet/wpf · error · ArgumentNullException

ArgumentNullException: relativeTo

Error message

ArgumentNullException: relativeTo

What it means

The ICollection<KeyValuePair<K,V>>.Add member of this internal ConcurrentDictionary is explicitly unimplemented and always throws NotImplementedException. Mutation of the collection is expected to go through the indexer setter or Add(K,V)-style members instead of the interface method.

Solutions

  1. Use the indexer assignment dict[key] = value instead of ICollection<T>.Add.
  2. Replace collection-initializer syntax ({ { k, v } }) with explicit indexer assignments.
  3. If a generic ICollection<T> consumer must work, adapt it to use the indexer via a small wrapper.
  4. Report to WPF if you depend on the interface contract; the member is a stub by design.

Example fix

// before
var d = new ConcurrentDictionary<string, object> { { "k", v } }; // NotImplementedException
// after
var d = new ConcurrentDictionary<string, object>();
d["k"] = v;
Defensive patterns

Strategy: validation

Validate before calling

// Avoid ICollection<T>.Add entirely; assert before use:
if (dict is ICollection<KeyValuePair<K,V>>) throw new NotSupportedException("Use indexer assignment, Add is a NotImplementedException stub");

Try / catch

try { coll.Add(pair); } catch (NotImplementedException) { dict[pair.Key] = pair.Value; }

Prevention

When it happens

Trigger: Calling Add(new KeyValuePair<K,V>(k,v)) directly, or passing the dictionary to code that uses ICollection<T>.Add (e.g. collection initializers like new ConcurrentDictionary<K,V> { { k, v } }).

Common situations: Collection-initializer syntax on the dictionary; generic algorithms written against ICollection<T>; LINQ-style bulk-insert helpers that call Add on the interface.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/bbf70cbb5ad110de. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationBuildTasks/MS/Internal/MarkupCompiler/PathInternal.cs:29

//   current platform (StringComparison.OrdinalIgnoreCase for Windows.)
//
//---------------------------------------------------------------------------

using System;
using System.IO;
using System.Text;

using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace MS.Internal
{
    internal sealed class PathInternal 
    {
        internal static string GetRelativePath(string relativeTo, string path, StringComparison comparisonType)
        {
            if (relativeTo == null)
                throw new ArgumentNullException(nameof(relativeTo));

            if (PathInternal.IsEffectivelyEmpty(relativeTo.AsSpan()))
                throw new ArgumentException(nameof(relativeTo));

            if (path == null)
                throw new ArgumentNullException(nameof(path));

            if (PathInternal.IsEffectivelyEmpty(path.AsSpan()))
                throw new ArgumentException(nameof(path));

            Debug.Assert(comparisonType == StringComparison.Ordinal || comparisonType == StringComparison.OrdinalIgnoreCase);

            relativeTo = Path.GetFullPath(relativeTo);
            path = Path.GetFullPath(path);

            // Need to check if the roots are different- if they are we need to return the "to" path.
            if (!PathInternal.AreRootsEqual(relativeTo, path, comparisonType))
                return path;

View on GitHub (pinned to 81131a70a4)