dotnet/wpf · error · ArgumentException

ArgumentException: relativeTo

Error message

ArgumentException: relativeTo

What it means

ICollection<KeyValuePair<K,V>>.Contains on this internal ConcurrentDictionary is a stub that always throws NotImplementedException. Membership testing of a KeyValuePair against the collection interface was never implemented; use key-based lookups instead.

Solutions

  1. Test membership with ContainsKey(key) and then compare the value from the indexer if a pair comparison is needed.
  2. Replace interface-level Contains calls with key-based checks.
  3. Wrap the dictionary in your own adapter implementing Contains via ContainsKey + value equality.
  4. File a WPF issue if the interface contract is required for your scenario.

Example fix

// before
bool has = ((ICollection<KeyValuePair<K,V>>)dict).Contains(pair); // throws
// after
bool has = dict.ContainsKey(pair.Key) && EqualityComparer<V>.Default.Equals(dict[pair.Key], pair.Value);
Defensive patterns

Strategy: validation

Validate before calling

bool contains = dict.ContainsKey(pair.Key) && EqualityComparer<V>.Default.Equals(dict[pair.Key], pair.Value);

Try / catch

try { coll.Contains(pair); } catch (NotImplementedException) { /* use ContainsKey-based check */ }

Prevention

When it happens

Trigger: Calling Contains(pair) on the ICollection<KeyValuePair<K,V>> interface, or LINQ/Contains-extension paths that bind to the interface member.

Common situations: Generic code checking whether a dictionary 'contains' a pair; test helpers asserting collection membership; code ported from Dictionary<K,V> where Contains worked via other members.

Related errors


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

Appendix: source

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

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;

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

View on GitHub (pinned to 81131a70a4)