dotnet/wpf · error · NotSupportedException
SR.ItemCollectionShouldUseInnerSyncRoot
Error message
SR.ItemCollectionShouldUseInnerSyncRoot
What it means
ItemCollection.SyncRoot throws NotSupportedException(SR.ItemCollectionShouldUseInnerSyncRoot) when the collection is in ItemsSource mode. In that mode the wrapper does not own the backing store, so locking on the wrapper's SyncRoot would synchronize on the wrong object; callers must lock the underlying collection's SyncRoot instead.
Solutions
- Lock on the underlying source collection's SyncRoot (or use its own synchronization) instead of Items.SyncRoot.
- Prefer dispatching all collection mutations to the UI thread rather than locking.
- Use a BindingOperations/CollectionView-safe pattern (e.g. lock the ObservableCollection's SyncRoot or a dedicated lock object you own).
Example fix
// before
lock (itemsControl.Items.SyncRoot) { source.Add(x); }
// after
var oc = (ObservableCollection<MyItem>)itemsControl.ItemsSource;
lock (((ICollection)oc).SyncRoot) { oc.Add(x); } Defensive patterns
Strategy: fallback
Validate before calling
if (items.IsUsingItemsSource)
{
var src = (ICollection)itemsControl.ItemsSource;
lock (src.SyncRoot) { /* mutate source */ }
} Type guard
static ICollection SourceCollection(ItemCollection c) => (ICollection)c.GetType().GetProperty("CollectionView")?.GetValue(c); Try / catch
try { return items.SyncRoot; }
catch (NotSupportedException) { return ((ICollection)itemsControl.ItemsSource).SyncRoot; } Prevention
- Never lock on Items.SyncRoot when ItemsSource is set
- Prefer single-threaded UI access via Dispatcher instead of locking
- Lock the source collection or a dedicated lock object
When it happens
Trigger: Accessing itemsControl.Items.SyncRoot while IsUsingItemsSource is true (ItemsSource assigned to a collection).
Common situations: Multi-threaded code locking on Items.SyncRoot to serialize updates; refactoring code that worked with direct Items.Add into ItemsSource binding without updating the locking strategy.
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
- ElementNotAvailableException
- (no message) NotSupportedException
- Processing is disabled while the Dispatcher is in this…
- Specified method is not supported.
- SR.BadTargetArray
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/63be0cc3f08a4a89.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemCollection.cs:749
}
}
/// <summary>
/// Returns an object to be used in thread synchronization.
/// </summary>
/// <exception cref="NotSupportedException">
/// ItemCollection cannot provide a sync root for synchronization while
/// in ItemsSource mode. Please use the ItemsSource directly to
/// get its sync root.
/// </exception>
object ICollection.SyncRoot
{
get
{
if (IsUsingItemsSource)
{
// see discussion in XML comment above.
throw new NotSupportedException(SR.ItemCollectionShouldUseInnerSyncRoot);
}
return _internalView.SyncRoot;
}
}
/// <summary>
/// Gets a value indicating whether the IList has a fixed size.
/// An ItemCollection can usually grow dynamically,
/// this call will commonly return FixedSize = False.
/// In ItemsSource mode, this call will return IsFixedSize = True.
/// </summary>
bool IList.IsFixedSize
{
get
{
return IsUsingItemsSource;
}View on GitHub (pinned to 81131a70a4)