Troubleshooting
Grouped by what you see. Most entries end with the check that distinguishes it from the symptom next to it — that is usually the part that saves the afternoon.
Ask this first
Which window? In a multiplayer PIE session, whether something fails on the client only or on both halves the search immediately.
- Client only → replication, or a client believing something it should not.
- Both → logic, and you can debug it in standalone where it is far easier.
The UI shows nothing
Panels are empty, but the gameplay debugger looks right
The debugger collects on the server, so it looking right does not prove the client has anything.
Almost always: the view was bound by pointer instead of by role. On a client the containers arrive after the HUD is built, so a view bound to the container that existed at that moment is bound to nothing, permanently.
Set Source Inventory (Inventory, Container Tag) ← use this
Set Source (Container) ← only for a chest you already hold
Confirm it with LogEDInventory at Verbose: a view says what it bound to and whether the container
was there yet.
A grid draws as a single line
The view has no container, so it cannot know its own dimensions. Same cause as above.
A bar shows the right number of empty cells but never fills
Also no container — but only in older builds, where a bar drew FallbackSlotCount cells regardless.
That fallback is design-time only now: at runtime, no container means no cells. If you see a
plausible-looking empty bar, check the binding rather than the contents.
Items behave oddly
Icons and names are blank, everything else works
The Asset Manager does not know where your item definitions live, so a FPrimaryAssetId cannot be
turned back into a definition. See
Installation.
Nothing errors, because nothing is wrong at the container level.
Dropping an item logs "could not resolve" and produces nothing
The same cause. Pickup works because the definition is in hand; dropping has to rebuild it from an id.
Two identical items refuse to stack
They differ in something that must not be merged away:
- per-stack state — different durability, ammo, charges;
- dynamic tags — one is stolen, bound or quest-reserved;
- one of them is promoted to a
UEDItemInstance.
All three are deliberate. Merging would have to invent a value or launder a mark.
Picking things up never fills the inventory
Something is accepting more than you think. The usual culprit is a slot layout with a permissive slot — an off-hand with empty Accepted Tags takes any item, which turns a paperdoll into six slots of overflow storage.
Give the container an Item Query so only equippable items are routed to it. The layout says what fits in a slot; the query says what the container accepts at all.
An item auto-equips when picked up
Equipment is being chosen by placement. Lower its Priority (the demo uses −100) and give it an Item Query. Priority orders; the query excludes.
Containers
Get Container returns nothing on a client
If it works on the server, the container has arrived but is not identifiable yet — the list and the containers replicate separately. Subscribe to On Containers Changed and re-resolve rather than resolving once.
If it fails on both, the tag does not match. Matching is hierarchical, so Inventory.Container finds
Inventory.Container.Hotbar but not the other way round.
The gameplay debugger reports no containers for a player who clearly has some
The debugger reads the actor under the cursor and the actors that stand in for it: from a Pawn it also reads the Controller and the PlayerState, and every line names the actor the container belongs to. So an inventory kept on the PlayerState — the usual arrangement, because it survives a respawn — shows up while pointing at the character.
If it still reports nothing, the header lists the actors it searched. A container missing from all of
them has genuinely not been built yet: containers are created in BeginPlay, on the authority only.
A bag does not open when equipped
Check, in order:
- The item has a Nested Container fragment with a container definition set.
- The fragment's Container Filter and Slot Filter match where the item actually is. A filter built wrong reads as "matches nothing" and never complains.
- Nothing else already holds that container tag — one container per identity, per inventory. The log says so when a second is refused.
To verify a filter, empty it temporarily. If the bag opens when carried, the filter is the problem.
Removing a container is refused
It belongs to an item. Move or remove the item and its container follows. Removing it directly would leave the item convinced it still had storage.
Items vanished when a bag was removed
Check the log for "no stranded-item handler took it". That warning means the contents had nowhere to go and were destroyed — a design gap being reported. Either make room, or add a handler that drops them. See Nested containers.
Multiplayer
A client's request on a chest does nothing
If you built the request by hand and sent it through a component on the chest, the engine dropped it: a Server RPC only travels an actor chain the client owns.
Use RequestTransaction on the container, which finds a route the client does own.
Changes appear on the server but never on the client
The container is not replicating. Check that the owning component has SetIsReplicatedByDefault(true)
and that the container was registered as a replicated subobject — both are automatic for the shipped
components.
A chest screen stays open across the map
No session was opened, so the server refused the request with NotAuthorized. OpenSession is
what grants a client access to a container it does not own — and it must be called on the server,
from whatever code handles the interaction. A client calling it is ignored and logged.
Editor
A container definition will not save
Validation refuses one with no Container Tag. That is its identity, and a container without one cannot be found by anything at runtime.
An item shows a validation warning about duplicate fragments
At most one fragment of each type per definition. The second would silently never be read.
A whole feature does nothing
Every transaction of one kind fails, and nothing else is wrong
FAILED (reason=NoExecutor ...), and once per type a warning saying nothing is registered to perform
it. The transaction struct exists; the executor that knows how to run it does not. One of three:
- the feature module that registers it is disabled in the
.uplugin - its Game Feature has not activated yet — check ordering, not the transaction
- it is your own transaction and nothing ever called
FEDTransactionExecutorRegistry::Register
This one reports itself even with Transaction Logging off, because there is nothing else to see: the transaction simply has no effect.
A server-only node in a Blueprint does nothing
Nodes marked ⬤ server need authority. Called on a client each now logs a warning naming itself
and the Request form to use instead. If you see one of those lines, the graph is running where it
cannot act — not where it is wrong.
Grants apply, but the ability does nothing when it fires
The ability activates and returns immediately, with no error. Almost always it is casting
GetCurrentSourceObject() to a type the item is not.
UEDGASLinkComponent hands the ability the item's UEDItemInstance — and a fast-path item, which
has no instance, gets the link component instead. An ability written against your own equipment
instance type gets neither. Override ResolveGrantSourceObject and return the object your abilities
expect; see
What a granted ability can ask about its item.
One system attached to the inventory simply never runs
The actor works, the inventory works, and your observer — visuals, a grant bridge, a counter — does nothing at all, with no error anywhere.
If the actor has no containers at all, it now says so once on the authority, about ten seconds
in: the observer is on the wrong actor, or on the right one before a Game Feature has added them.
Raise Silence Report Seconds if your containers legitimately arrive late, or set it to 0.
If the actor has containers, nothing is logged, and that is on purpose — an observer whose
Can Observe is unsatisfied may simply be waiting, and a controller between rounds with no pawn is
right to sit idle. Check the prerequisite your subclass gates on yourself: a possessed pawn, an
avatar mesh, authority.
Authority-only: several shipped observers are dormant by design on clients, because their work is server-side and reaches clients by replication.
Items grant nothing, and only for bots
UEDGASLinkComponent now says at BeginPlay when its owner does not implement
IAbilitySystemInterface — there is no ability system for it to grant to, and there never will be,
so it sits dormant and every item's grants are quietly skipped. The symptom reads as the grants being
broken rather than the wiring.
This is the shape it usually takes: a PlayerController forwards to its PlayerState's ability
system, the AIController beside it does not, and the same containers on the same kind of actor
grant for players and silently grant nothing for bots.
After a respawn the inventory is intact but the pawn is empty-handed
Expected, and yours to finish. Containers on a Controller or PlayerState survive; anything an
observer applied to the pawn died with it, and a respawn fires no inventory event to prompt a
re-apply. Gate CanObserve on the avatar and call NotifyObservationContextChanged() from
OnPossessedPawnChanged — see
Keeping the inventory across a respawn.
Getting more out of the log
[Core.Log]
LogEDInventory=Verbose
At Display you get transaction outcomes. At Verbose you also get what each view binds to and what a client receives, which is what separates "the container did not arrive" from "it arrived and the view is not looking at it".
Still stuck
Reproduce in a 2-player PIE session, note which window misbehaves, and capture
Saved/Logs/YourProject.log with LogEDInventory at Verbose. That log usually contains the answer,
and it always contains enough to ask a precise question.
Turn on Transaction Logging (Project Settings → Plugins → EDInventory) before you do: every
transaction then reports its outcome, and a refused client request names the reason, the actor and
the container. FAILED (reason=NotAuthorized ...) is the whole diagnosis for most multiplayer
problems — it means nothing has granted that player access to that container yet.
Then bring it to Discord, which is where support happens.