dotnet/wpf · error · ArgumentOutOfRangeException
throw new ArgumentOutOfRangeException(nameof(oldList));
Error message
throw new ArgumentOutOfRangeException(nameof(oldList));
What it means
ThreeItemList.Promote(FrugalListBase<T> oldList) moves data from a smaller storage variant into this three-slot list. After copying entries, a switch on oldCount handles 1/2/3 items; any other count falls into default and throws ArgumentOutOfRangeException named 'oldList'. This means the old list reported a Count the three-item variant cannot classify — an internal invariant violation (count < 0 or > 3, or a count that should have taken the 'target too small' branch).
Solutions
- Ensure Promote is only called with oldList variants whose Count fits the target (0..3 for ThreeItemList).
- Check oldList.Count before promoting: if it exceeds the target capacity, use the larger variant (SixItemList/ArrayItemList) instead.
- If you subclass FrugalListBase, keep Count accurate and consistent with the number of stored entries.
- Reproducible outside custom code? File a dotnet/wpf bug; this is an internal invariant failure.
Example fix
// before
threeList.Promote(sixItemListWithCount4); // count 4 hits default case
// after
if (sixItemListWithCount4.Count <= 3)
{
threeList.Promote(sixItemListWithCount4);
}
else
{
var bigger = new ArrayItemList<T>(sixItemListWithCount4);
bigger.Promote(sixItemListWithCount4);
} Defensive patterns
Strategy: validation
Validate before calling
if (oldList is null) throw new ArgumentNullException(nameof(oldList));
if (oldList.Count is < 0 or > 3) throw new InvalidOperationException("Source count not promotable into ThreeItemList");
target.Promote(oldList); Type guard
bool CanPromoteToThreeItem<T>(FrugalListBase<T> src) => src is { Count: >= 0 and <= 3 }; Try / catch
try { target.Promote(oldList); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "oldList")
{
target = new ArrayItemList<T>(oldList.Count);
target.Promote(oldList);
} Prevention
- Match the target variant's capacity to the source Count before promoting.
- Keep Count accurate in any FrugalListBase subclass.
- Promote through the documented variant chain (Single→Three→Six→Array), skipping levels only when capacity is verified.
When it happens
Trigger: Promote is called with an oldList whose Count is outside {0,1,2,3} while this list is large enough (Count >= oldCount), e.g. a corrupt/oversized FrugalListBase implementation, or a SixItemList passed to a ThreeItemList.Promote with 4+ items yet claiming to fit.
Common situations: Seen in WPF property-value caching when the effective-values storage is promoted through the FrugalList/FrugalObjectList variant chain; arises from internal bugs or reflection misuse, not typical application code.
Related errors
- SR.Visual_ArgumentOutOfRange
- args
- args
- ArgumentOutOfRangeException(authenticationType)
- ArgumentOutOfRangeException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/f7475ab59034a409.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs:606
SetAt(0, oldList.EntryAt(0));
SetAt(1, oldList.EntryAt(1));
SetAt(2, oldList.EntryAt(2));
break;
case 2:
SetAt(0, oldList.EntryAt(0));
SetAt(1, oldList.EntryAt(1));
break;
case 1:
SetAt(0, oldList.EntryAt(0));
break;
case 0:
break;
default:
throw new ArgumentOutOfRangeException(nameof(oldList));
}
}
else
{
// this list is smaller than oldList
throw new ArgumentException(SR.Format(SR.FrugalList_TargetMapCannotHoldAllData, oldList.ToString(), this.ToString()), nameof(oldList));
}
}
// Class specific implementation to avoid virtual method calls and additional logic
public void Promote(SingleItemList<T> oldList)
{
SetCount(oldList.Count);
SetAt(0, oldList.EntryAt(0));
}
// Class specific implementation to avoid virtual method calls and additional logic
public void Promote(ThreeItemList<T> oldList)View on GitHub (pinned to 81131a70a4)