dotnet/wpf · error · ArgumentException

SR.Stylus_PlugInIsDuplicated

Error message

SR.Stylus_PlugInIsDuplicated

What it means

StylusPlugInCollection.InsertItem rejects a plug-in that is already in the collection, throwing ArgumentException with SR.Stylus_PlugInIsDuplicated. Each StylusPlugIn may be attached to a collection only once.

Solutions

  1. Guard with IndexOf before adding: only Add when IndexOf(plugin) == -1
  2. Track whether the plug-in was already attached (bool flag) and skip duplicate adds
  3. Note the same instance cannot be reused across two collections of the same element; create a new instance if needed for a second element

Example fix

// before
void Attach(StylusPlugIn plugin) => inkCanvas.StylusPlugIns.Add(plugin);
// after
void Attach(StylusPlugIn plugin)
{
    if (inkCanvas.StylusPlugIns.IndexOf(plugin) == -1)
    {
        inkCanvas.StylusPlugIns.Add(plugin);
    }
}
Defensive patterns

Strategy: validation

Validate before calling

if (plugIns.IndexOf(plugin) == -1) plugIns.Add(plugin);

Try / catch

try { plugIns.Add(plugin); } catch (ArgumentException ex) when (ex.Message.Contains("PlugInIsDuplicated") || ex.ParamName == "plugIn") { /* already attached */ }

Prevention

When it happens

Trigger: Calling stylusPlugIns.Add(plugin) or Insert with a plug-in instance already present (IndexOf(plugIn) != -1).

Common situations: Re-adding the same singleton plug-in on an event (e.g. Loaded firing twice, or adding in both constructor and Loaded), or sharing one StylusPlugIn instance across several operations without tracking membership.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusPlugInCollection.cs:43

        /// Insert a StylusPlugIn in the collection at a specific index. 
        /// This method should be called from the application context only
        /// </summary>
        /// <param name="index">index at which to insert the StylusPlugIn object</param>
        /// <param name="plugIn">StylusPlugIn object to insert, downcast to an object</param>
        protected override void InsertItem(int index, StylusPlugIn plugIn)
        {
            // Verify it's called from the app dispatcher
            _element.VerifyAccess();

            // Validate the input parameter
            if (null == plugIn)
            {
                throw new ArgumentNullException(nameof(plugIn), SR.Stylus_PlugInIsNull);
            }

            if (IndexOf(plugIn) != -1)
            {
                throw new ArgumentException(SR.Stylus_PlugInIsDuplicated, nameof(plugIn));
            }

            // Disable processing of the queue during blocking operations to prevent unrelated reentrancy
            // which a call to Lock() can cause.
            ExecuteWithPotentialDispatcherDisable(() =>
            {
                if (_stylusPlugInCollectionImpl.IsActiveForInput)
                {
                    // If we are currently active for input then we have a _penContexts that we must lock!
                    ExecuteWithPotentialLock(() =>
                     {
                         System.Diagnostics.Debug.Assert(this.Count > 0); // If active must have more than one plugin already
                         base.InsertItem(index, plugIn);
                         plugIn.Added(this);
                     });
                }
                else
                {

View on GitHub (pinned to 81131a70a4)