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
- Null-check the item at the call site before EquipItem and bail/log instead of throwing.
- Fix the upstream lookup so it never yields null (or handle the not-found case).
- Guard EntityRef dereferences before treating them as valid Items.
- 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
- Null-check Items from any lookup before equipping.
- Treat EntityRef derefs as nullable.
- Validate item is not disposed/already-parented.
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
- invalid slot index: {slotIndex}
- to json error {obj.GetType().FullName} {e}
- MethodHook:targetMethod and replacementMethod and proxyMetho
- hot update assembly name cann't be empty
- invalid capacity: {capacity}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/29042337b3f50d6f.
Report an issue: GitHub.