egametang/ET · error

invalid slot index: {slotIndex}

Error message

invalid slot index: {slotIndex}

What it means

Thrown by ItemComponentSystem.EnsureSlotIndex when a caller passes a negative slot index to a slot operation (SetSlotItem, UpdateItem, etc.). The inventory component validates that slot indices fall within [0, Capacity) before mutating the SlotItems list; a negative index fails the first guard.

Source

Thrown at Packages/cn.etetet.item/Scripts/Hotfix/Client/ItemComponentSystem.cs:199

        public static void ClearSlot(this ItemComponent self, int slotIndex)
        {
            if ((uint)slotIndex >= (uint)self.SlotItems.Count)
            {
                return;
            }

            self.SlotItems[slotIndex] = default;
        }

        #endregion

        #region 私有方法

        private static void EnsureSlotIndex(ItemComponent self, int slotIndex)
        {
            if (slotIndex < 0)
            {
                throw new Exception($"invalid slot index: {slotIndex}");
            }

            if (slotIndex >= self.Capacity)
            {
                throw new Exception($"slot index {slotIndex} exceeds capacity {self.Capacity}");
            }
        }

        private static void EnsureSlotContainerSize(ItemComponent self, int size)
        {
            if (size <= 0)
            {
                return;
            }

            if (self.SlotItems.Count >= size)
            {
                return;

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Validate the slot index at the source (network handler, UI event) before calling UpdateItem/SetSlotItem.
  2. If -1 is used as a sentinel for unassigned, convert it to a valid representation (a separate nullable field or a dedicated unslotted collection) before reaching the inventory component.
  3. Add a precondition check or unit test asserting slotIndex >= 0 for all call sites.
  4. Consider clamping or rejecting server payloads with invalid slot indices at the deserialization boundary.

Example fix

// before
itemComponent.UpdateItem(itemId, slotIndex, configId, count);
// after
if ((uint)slotIndex < (uint)itemComponent.Capacity)
{
    itemComponent.UpdateItem(itemId, slotIndex, configId, count);
}
else
{
    Log.Warning($"rejected item update with invalid slot {slotIndex}");
}
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling slot operations
public static bool TryUpdateItem(this ItemComponent self, long itemId, int slotIndex, int configId, int count)
{
    if ((uint)slotIndex >= (uint)self.Capacity) return false;
    self.UpdateItem(itemId, slotIndex, configId, count);
    return true;
}

Type guard

// Guard: true if the slot index is within valid inventory bounds
static bool IsValidSlot(ItemComponent component, int slotIndex)
    => slotIndex >= 0 && slotIndex < component.Capacity;

Prevention

When it happens

Trigger: EnsureSlotIndex(self, slotIndex) is invoked at the start of SetSlotItem and UpdateItem. If slotIndex < 0 the method throws immediately. A separate guard (line 204) covers slotIndex >= Capacity.

Common situations: Server-sent item data with an unset/default slot index (0 is valid, but -1 is a common sentinel for no slot); client code computing a slot from an off-by-one calculation; deserialized JSON with a missing slot field defaulting to a negative; UI code passing a clicked-slot index before bounds checking.

Related errors


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