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
- Validate the slot index at the source (network handler, UI event) before calling UpdateItem/SetSlotItem.
- 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.
- Add a precondition check or unit test asserting slotIndex >= 0 for all call sites.
- 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
- Validate slot indices at the network deserialization boundary before they reach the inventory component.
- Use a sentinel-free representation for unslotted items (separate field or collection) instead of negative indices.
- Add unit tests covering slotIndex = -1, 0, Capacity-1, Capacity to lock in boundary behavior.
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
- Item cannot be null
- ArgumentOutOfRange_Index
- Arg_ArrayPlusOffTooSmall
- Argument_IncompatibleArrayType
- string mode < 0: {strText} {mode}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/a542ba957fd1e922.
Report an issue: GitHub.