{"record":{"id":"87e32308019f1f5d","repo":"EllanJiang/GameFramework","slug":"first-is-invalid","errorCode":null,"errorMessage":"First is invalid.","messagePattern":"First is invalid\\.","errorType":"exception","errorClass":"GameFrameworkException","httpStatus":null,"severity":"error","filePath":"GameFramework/Base/GameFrameworkLinkedList.cs","lineNumber":307,"sourceCode":"        /// <summary>\n        /// 从链表中移除指定的结点。\n        /// </summary>\n        /// <param name=\"node\">指定的结点。</param>\n        public void Remove(LinkedListNode<T> node)\n        {\n            m_LinkedList.Remove(node);\n            ReleaseNode(node);\n        }\n\n        /// <summary>\n        /// 移除位于链表开头处的结点。\n        /// </summary>\n        public void RemoveFirst()\n        {\n            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();","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/EllanJiang/GameFramework/blob/d0c010b05167c58e92350449d04864a91ca13fd2/GameFramework/Base/GameFrameworkLinkedList.cs#L289-L325","documentation":"GameFrameworkLinkedList<T>.RemoveFirst tries to remove the first node of the underlying LinkedList and release it back to the node pool. The list's First node is null (the list is empty), which the wrapper treats as an invalid state and throws instead of letting the raw list silently do nothing or throw its own error.","triggerScenarios":"Calling RemoveFirst() on an empty GameFrameworkLinkedList — e.g. draining a queue with RemoveFirst without checking Count, or after all nodes were already removed.","commonSituations":"Consumer loops popping from a pooled linked list until empty; double-drain after Clear; logic bugs where items were consumed elsewhere before RemoveFirst is called.","solutions":["Check Count > 0 (or First != null) before calling RemoveFirst","Use TryGetFirst/First value access guards or restructure the loop to use a while (list.Count > 0) condition","Catch GameFrameworkException and treat empty list as a no-op if acceptable"],"exampleFix":"// before\nwhile (true) { list.RemoveFirst(); }\n// after\nwhile (list.Count > 0) { list.RemoveFirst(); }","handlingStrategy":"validation","validationCode":"if (list.Count > 0) { list.RemoveFirst(); }","typeGuard":"static bool CanRemoveFirst<T>(GameFrameworkLinkedList<T> list) => list != null && list.Count > 0;","tryCatchPattern":"try { list.RemoveFirst(); }\ncatch (GameFrameworkException) { /* list already empty; treat as no-op */ }","preventionTips":["Check Count before RemoveFirst/RemoveLast in drain loops","Avoid calling RemoveFirst after Clear or after another consumer emptied the list","Centralize pop logic in one helper that guards emptiness"],"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"}