{"record":{"id":"fa22f74ef6e4fb9c","repo":"EllanJiang/GameFramework","slug":"last-is-invalid","errorCode":null,"errorMessage":"Last is invalid.","messagePattern":"Last is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/GameFrameworkLinkedList.cs","lineNumber":322,"sourceCode":"            LinkedListNode<T> first = m_LinkedList.First;\n            if (first == null)\n            {\n                throw new GameFrameworkException(\"First is invalid.\");\n            }\n\n            m_LinkedList.RemoveFirst();\n            ReleaseNode(first);\n        }\n\n        /// <summary>\n        /// 移除位于链表结尾处的结点。\n        /// </summary>\n        public void RemoveLast()\n        {\n            LinkedListNode<T> last = m_LinkedList.Last;\n            if (last == null)\n            {\n                throw new GameFrameworkException(\"Last is invalid.\");\n            }\n\n            m_LinkedList.RemoveLast();\n            ReleaseNode(last);\n        }\n\n        /// <summary>\n        /// 返回循环访问集合的枚举数。\n        /// </summary>\n        /// <returns>循环访问集合的枚举数。</returns>\n        public Enumerator GetEnumerator()\n        {\n            return new Enumerator(m_LinkedList);\n        }\n\n        private LinkedListNode<T> AcquireNode(T value)\n        {\n            LinkedListNode<T> node = null;","sourceCodeStart":304,"sourceCodeEnd":340,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/GameFrameworkLinkedList.cs#L304-L340","documentation":"GameFrameworkLinkedList<T>.RemoveLast tries to remove the last node of the underlying LinkedList and release it to the node pool. When the list's Last node is null (the list is empty), the wrapper throws this error rather than operating on an invalid state.","triggerScenarios":"Calling RemoveLast() on an empty GameFrameworkLinkedList — e.g. popping from the tail without checking whether any elements remain, or calling it twice after the list became empty.","commonSituations":"LIFO-style drains from the tail of a pooled linked list; off-by-one loops; interleaved code paths where another component already emptied the list.","solutions":["Check Count > 0 (or Last != null) before calling RemoveLast","Restructure the drain loop as while (list.Count > 0) { list.RemoveLast(); }","Catch GameFrameworkException around RemoveLast if an empty list is an expected, tolerable state"],"exampleFix":"// before\nif (needPop) { list.RemoveLast(); }\n// after\nif (needPop && list.Count > 0) { list.RemoveLast(); }","handlingStrategy":"validation","validationCode":"if (list.Count > 0) { list.RemoveLast(); }","typeGuard":"static bool CanRemoveLast<T>(GameFrameworkLinkedList<T> list) => list != null && list.Count > 0;","tryCatchPattern":"try { list.RemoveLast(); }\ncatch (GameFrameworkException) { /* list already empty; treat as no-op */ }","preventionTips":["Guard tail-pops with a Count > 0 check","Keep single ownership of the list so no other path empties it unexpectedly","Prefer while (list.Count > 0) loops over unbounded pop loops"],"tags":["gameframework","linked-list","empty-collection"],"backgroundTag":"empty-required-field","analyzedSha":"d0c010b05167c58e92350449d04864a91ca13fd2","analyzedAt":"2026-09-15T13:37:15.352Z","contentChangedAt":"2026-09-15T13:37:15.352Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}