{"record":{"id":"f7475ab59034a409","repo":"dotnet/wpf","slug":"throw-new-argumentoutofrangeexception-nameof-oldlist","errorCode":null,"errorMessage":"throw new ArgumentOutOfRangeException(nameof(oldList));","messagePattern":"throw new ArgumentOutOfRangeException\\(nameof\\(oldList\\)\\);","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs","lineNumber":606,"sourceCode":"                        SetAt(0, oldList.EntryAt(0));\n                        SetAt(1, oldList.EntryAt(1));\n                        SetAt(2, oldList.EntryAt(2));\n                        break;\n\n                    case 2:\n                        SetAt(0, oldList.EntryAt(0));\n                        SetAt(1, oldList.EntryAt(1));\n                        break;\n\n                    case 1:\n                        SetAt(0, oldList.EntryAt(0));\n                        break;\n\n                    case 0:\n                        break;\n\n                    default:\n                        throw new ArgumentOutOfRangeException(nameof(oldList));\n                }\n            }\n            else\n            {\n                // this list is smaller than oldList\n                throw new ArgumentException(SR.Format(SR.FrugalList_TargetMapCannotHoldAllData, oldList.ToString(), this.ToString()), nameof(oldList));\n            }\n        }\n\n        // Class specific implementation to avoid virtual method calls and additional logic\n        public void Promote(SingleItemList<T> oldList)\n        {\n            SetCount(oldList.Count);\n            SetAt(0, oldList.EntryAt(0));\n        }\n\n        // Class specific implementation to avoid virtual method calls and additional logic\n        public void Promote(ThreeItemList<T> oldList)","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/Shared/MS/Utility/FrugalList.cs#L588-L624","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nthreeList.Promote(sixItemListWithCount4); // count 4 hits default case\n// after\nif (sixItemListWithCount4.Count <= 3)\n{\n    threeList.Promote(sixItemListWithCount4);\n}\nelse\n{\n    var bigger = new ArrayItemList<T>(sixItemListWithCount4);\n    bigger.Promote(sixItemListWithCount4);\n}","handlingStrategy":"validation","validationCode":"if (oldList is null) throw new ArgumentNullException(nameof(oldList));\nif (oldList.Count is < 0 or > 3) throw new InvalidOperationException(\"Source count not promotable into ThreeItemList\");\ntarget.Promote(oldList);","typeGuard":"bool CanPromoteToThreeItem<T>(FrugalListBase<T> src) => src is { Count: >= 0 and <= 3 };","tryCatchPattern":"try { target.Promote(oldList); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"oldList\")\n{\n    target = new ArrayItemList<T>(oldList.Count);\n    target.Promote(oldList);\n}","preventionTips":["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."],"tags":["argument-out-of-range","wpf","internal-invariant"],"backgroundTag":"argument-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}