egametang/ET · error · System.Exception

Item cannot be null

Error message

Item cannot be null

What it means

Explicit ArgumentNullException-style guard in EquipmentComponentSystem.EquipItem (line 34): EquipItem throws 'Item cannot be null' when the caller passes a null Item. This is a programming-contract failure in the caller, not a runtime data problem - the equipment component never received a valid item to slot.

Source

Thrown at Packages/cn.etetet.equipment/Scripts/Hotfix/Server/EquipmentComponentSystem.cs:34

        [EntitySystem]
        private static void Destroy(this EquipmentComponent self)
        {
            self.EquippedItems.Clear();
        }

        #endregion

        #region 业务方法

        /// <summary>
        /// 穿戴装备(将Item从背包移到装备槽位)
        /// </summary>
        public static void EquipItem(this EquipmentComponent self, Item item, EquipmentSlotType slotType)
        {
            if (item == null)
            {
                throw new System.Exception("Item cannot be null");
            }

            self.AddChild(item);

            // 检查Item是否有装备组件
            item.AddComponent<EquipmentItemComponent>();


            // 如果该槽位已有装备,先卸下
            if (self.EquippedItems.ContainsKey(slotType))
            {
                Item oldItem = self.EquippedItems[slotType];
                if (oldItem != null)
                {
                    // 卸下旧装备,设置SlotIndex为-1表示未装备
                    oldItem.SlotIndex = -1;
                }
            }

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Null-check the item at the call site before EquipItem and bail/log instead of throwing.
  2. Fix the upstream lookup so it never yields null (or handle the not-found case).
  3. Guard EntityRef dereferences before treating them as valid Items.
  4. Add an audit of the equip flow to confirm item lifecycle.

Example fix

// before
comp.EquipItem(bag.GetItem(id), slot);

// after
Item item = bag.GetItem(id);
if (item == null) { Log.Warning($"equip: item {id} not found"); return; }
comp.EquipItem(item, slot);
Defensive patterns

Strategy: validation

Validate before calling

if (item == null) throw new ArgumentNullException(nameof(item));

Type guard

static bool CanEquip(Item item) => item != null && item.Parent == null; // not already parented

Prevention

When it happens

Trigger: Calling equipmentComp.EquipItem(null, slotType), e.g. after a lookup that returned null (item not found in bag, already-removed item, EntityRef that was disposed), or passing an item before it was created/loaded.

Common situations: UI equip button wired to a null selected item, inventory lookup miss fed straight to EquipItem, using an Item after RemoveFromParent/dispose, race where item is freed mid-request.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/29042337b3f50d6f. Report an issue: GitHub.