{"record":{"id":"7a2d1b09e31b994a","repo":"AvaloniaUI/Avalonia","slug":"stack-was-empty","errorCode":null,"errorMessage":"Stack was empty.","messagePattern":"Stack was empty\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Collections/Pooled/PooledStack.cs","lineNumber":574,"sourceCode":"        public T[] ToArray()\n        {\n            if (_size == 0)\n                return Array.Empty<T>();\n\n            T[] objArray = new T[_size];\n            int i = 0;\n            while (i < _size)\n            {\n                objArray[i] = _array[_size - i - 1];\n                i++;\n            }\n            return objArray;\n        }\n\n        private void ThrowForEmptyStack()\n        {\n            Debug.Assert(_size == 0);\n            throw new InvalidOperationException(\"Stack was empty.\");\n        }\n\n        private void ReturnArray(T[]? replaceWith = null)\n        {\n            if (_array?.Length > 0)\n            {\n                try\n                {\n                    _pool.Return(_array, clearArray: _clearOnFree);\n                }\n                catch (ArgumentException)\n                {\n                    // oh well, the array pool didn't like our array\n                }\n            }\n\n            if (!(replaceWith is null))\n            {","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Collections/Pooled/PooledStack.cs#L556-L592","documentation":"InvalidOperationException \"Stack was empty.\" thrown by PooledStack<T>.ThrowForEmptyStack(), called from Peek() and Pop() when the stack has zero elements (`(uint)(size-1) >= (uint)array.Length` is the bounds-safe empty check). It signals an attempt to read/remove from a drained stack rather than returning default. TryPeek/TryPop exist as the non-throwing alternatives.","triggerScenarios":"Calling `stack.Peek()` or `stack.Pop()` on an empty PooledStack<T>; popping in a loop past the last element; consuming a stack that another code path already drained.","commonSituations":"A drain loop like `while (true) stack.Pop();` without a Count check; shared/multi-step processing where an earlier step emptied the stack; assuming a queue/stack is non-empty after a filter.","solutions":["Use TryPop/TryPeek which return false instead of throwing.","Guard with `if (stack.Count > 0)` before Peek/Pop.","Bound the drain loop with `while (stack.Count > 0)`."],"exampleFix":"// before\nwhile (true)\n    DoWork(stack.Pop()); // throws when drained\n\n// after\nwhile (stack.TryPop(out var item))\n    DoWork(item);","handlingStrategy":"validation","validationCode":"if (!stack.TryPop(out var item))\n    return; // stack empty, handle gracefully\nDoWork(item);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer TryPop/TryPeek over Pop/Peek when emptiness is possible.","Guard drain loops with `while (stack.Count > 0)`.","Document whether a method requires a non-empty stack at its entry."],"tags":["csharp","pooled","stack","invalid-operation","collections"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}