dotnet/wpf · error · ArgumentException

Unsupported Selection

Error message

Unsupported Selection

What it means

LocatorManager.GenerateLocators builds content locators for an annotation selection. It first resolves an ISelectionProcessor that can handle the selection's type; if no processor is registered for that selection type, it cannot produce locators and throws this ArgumentException.

Solutions

  1. Inspect the selection object's runtime type and ensure it is a type supported by the annotations framework (e.g. an ITextSelection/TextSelection).
  2. Verify the selection actually contains data; create it from a real selection source (e.g. a FlowDocumentReader/TextBox selection) rather than constructing it manually.
  3. Register a custom ISelectionProcessor for the selection type if you use a custom selection class, before calling GenerateLocators.
  4. Catch ArgumentException around GenerateLocators and degrade gracefully (skip locator generation).

Example fix

// before
var locators = locatorManager.GenerateLocators(myCustomSelectionObject);
// after
if (AnnotationSelectionHelper.IsSupportedSelection(myCustomSelectionObject))
{
    var locators = locatorManager.GenerateLocators(myCustomSelectionObject);
}
else
{
    locators = null; // fall back: cannot anchor this selection
}
Defensive patterns

Strategy: type-guard

Validate before calling

var supported = selection != null && LocatorManager.FindSelectionProcessor(selection.GetType()) != null;
if (!supported) throw new InvalidOperationException("No selection processor for " + selection.GetType());

Type guard

static bool IsSupportedSelection(object selection, LocatorManager mgr) => selection != null && mgr.GetSelectionProcessor(selection.GetType()) != null;

Try / catch

try { locators = locatorManager.GenerateLocators(selection); }
catch (ArgumentException ex) when (ex.Message.Contains("Unsupported Selection")) { locators = null; }

Prevention

When it happens

Trigger: Calling LocatorManager.GenerateLocators(selection) with a selection object whose runtime type has no matching ISelectionProcessor registered (e.g. a custom or non-standard selection type, or a TextRange/TextSelection passed where the framework's TextSelectionHelper path is unavailable).

Common situations: Passing an arbitrary object instead of a supported selection (e.g. a string, DataObject or a UIElement instead of a TextSelection-like object); running in an environment where the text selection processor pipeline failed to initialize; custom annotation hosts that subclass selections without registering a processor.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/Annotations/Anchoring/LocatorManager.cs:348

        /// an empty list</returns>
        /// <exception cref="ArgumentNullException">if selection is null</exception>
        /// <exception cref="ArgumentException">if no processor is registered for
        /// selection's Type</exception>
        public IList<ContentLocatorBase> GenerateLocators(Object selection)
        {
            VerifyAccess();
            ArgumentNullException.ThrowIfNull(selection);

            ICollection nodes = null;
            SelectionProcessor selProcessor = GetSelectionProcessor(selection.GetType());

            if (selProcessor != null)
            {
                nodes = (ICollection)selProcessor.GetSelectedNodes(selection);
            }
            else
            {
                throw new ArgumentException("Unsupported Selection", nameof(selection));
            }

            IList<ContentLocatorBase> returnLocators = null;
            PathNode pathRoot = PathNode.BuildPathForElements(nodes);

            if (pathRoot != null)
            {
                SubTreeProcessor processor = GetSubTreeProcessor(pathRoot.Node);
                Debug.Assert(processor != null, "SubtreeProcessor can not be null");

                returnLocators = GenerateLocators(processor, pathRoot, selection);
            }

            // We never return null.  A misbehaved processor might return null so we fix it up.
            if (returnLocators == null)
                returnLocators = new List<ContentLocatorBase>(0);

            return returnLocators;

View on GitHub (pinned to 81131a70a4)