dotnet/wpf · error · ArgumentException

ArgumentException: path

Error message

ArgumentException: path

What it means

ICollection<KeyValuePair<K,V>>.Remove(item) on this internal ConcurrentDictionary is a stub that always throws NotImplementedException. Pair-based removal through the collection interface is not supported.

Solutions

  1. Remove entries with the key-based Remove(key) member instead of the pair-based interface method.
  2. Guard the removal with ContainsKey if existence matters.
  3. Adapt generic ICollection<T> consumers to call the key-based Remove.
  4. File a WPF issue if the interface contract is required.

Example fix

// before
((ICollection<KeyValuePair<K,V>>)dict).Remove(pair); // throws
// after
dict.Remove(pair.Key);
Defensive patterns

Strategy: validation

Validate before calling

if (dict.ContainsKey(item.Key)) dict.Remove(item.Key);

Try / catch

try { coll.Remove(pair); } catch (NotImplementedException) { dict.Remove(pair.Key); }

Prevention

When it happens

Trigger: Calling Remove(pair) via the ICollection<KeyValuePair<K,V>> interface; generic removal helpers or LINQ-style code paths binding to the interface member.

Common situations: Generic collection-editing utilities; code ported from Dictionary<K,V>; test code clearing entries through the interface.

Related errors


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

Appendix: source

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

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;

            int commonLength = PathInternal.GetCommonPathLength(relativeTo, path, ignoreCase: comparisonType == StringComparison.OrdinalIgnoreCase);

            // If there is nothing in common they can't share the same root, return the "to" path as is.
            if (commonLength == 0)
                return path;

            // Trailing separators aren't significant for comparison
            int relativeToLength = relativeTo.Length;

View on GitHub (pinned to 81131a70a4)