egametang/ET · error
bag is full
Error message
bag is full
What it means
Thrown by ItemHelper.AddItem when FindEmptySlot() returns -1, meaning no empty slot remains after stacking into existing partial stacks. The bag is full and the remaining count cannot be placed, so the operation aborts. Note this throw happens mid-operation, AFTER some items may already have been stacked/created and client notifications partially sent — partial state is a real concern.
Source
Thrown at Packages/cn.etetet.item/Scripts/Hotfix/Server/ItemHelper.cs:80
item.AddCount(addCount);
remainCount -= addCount;
updatedItemIds.Add(item.Id);
if (remainCount <= 0)
{
break;
}
}
}
}
// 需要创建新物品
while (remainCount > 0)
{
int slotIndex = self.FindEmptySlot();
if (slotIndex < 0)
{
throw new Exception("bag is full");
}
int addCount = System.Math.Min(remainCount, maxStack);
Item newItem = self.AddChild<Item>();
newItem.ConfigId = configId;
newItem.Count = addCount;
self.SetSlotItem(slotIndex, newItem);
updatedItemIds.Add(newItem.Id);
remainCount -= addCount;
}
// 通知客户端物品更新
foreach (long itemId in updatedItemIds)
{
Item item = self.GetItemById(itemId);
if (item != null)
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Pre-check available space: estimate slots needed (ceil(remainCount / maxStack) minus partial-stack room) and compare against free slots before calling AddItem.
- Use IsFull()/GetUsedSlotCount() to refuse the grant upstream and return an error code to the caller.
- Make AddItem transactional: snapshot state, and on 'bag is full' roll back any partial stacks/items already created so the bag isn't left half-modified.
Example fix
// before
ItemHelper.AddItem(comp, configId, count, reason); // may throw mid-way
// after — pre-check free space
int free = comp.Capacity - comp.GetUsedSlotCount();
if (comp.IsFull()) { /* return ERR_BagFull */ return; }
ItemHelper.AddItem(comp, configId, Math.Min(count, /*slotsNeeded*/), reason); Defensive patterns
Strategy: validation
Validate before calling
public static bool CanAddItem(ItemComponent self, int configId, int count)
{
var cat = self.Fiber().GetSingleton<ItemConfigCategory>();
var cfg = cat.Get(configId);
if (cfg == null) return false;
int maxStack = cfg.MaxStack > 1 ? cfg.MaxStack : 1;
// free slots available
int free = self.Capacity - self.GetUsedSlotCount();
// approximate: each free slot holds maxStack; ignore partial-stack room for a conservative check
return free * maxStack >= count;
}
// usage
if (!CanAddItem(comp, configId, count)) { /* return ERR_BagFull */ } Try / catch
try { ItemHelper.AddItem(comp, configId, count, reason); }
catch (Exception e) when (e.Message.Contains("bag is full"))
{ /* return error code to caller; note partial state risk */ } Prevention
- Pre-check free space before granting.
- Make AddItem transactional so partial adds roll back on 'bag full'.
- For non-stackable items, treat each unit as needing its own slot.
When it happens
Trigger: AddItem requests more of an item than can fit: stacking exhausts remainCount incompletely, then the while-loop calls FindEmptySlot and gets -1. Triggered when GetUsedSlotCount >= Capacity and the item cannot be fully stacked onto existing slots.
Common situations: Granting a large reward into a nearly-full bag; non-stackable items (MaxStack <= 1) with no free slots; a design that doesn't pre-check capacity before granting.
Related errors
- invalid capacity: {capacity}
- slot index {slotIndex} exceeds capacity {self.Capacity}
- invalid item count
- item config not found: {configId}
- slot index {slotIndex} exceeds capacity {self.Capacity}
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/9d1bc5b405e51760.
Report an issue: GitHub.