Troubleshooting
Most AG-UI integration issues are event-shape problems. Start by checking what your backend actually emits against the Event Mapping.
#Nothing renders
Check the provider first.
Then make sure the component uses the provided agent:
If you inject AG_UI_AGENT manually, the token must be provided in the same Angular injector tree.
#User messages appear, but no assistant response
submit() optimistically appends the user message before calling source.runAgent(). If the user message appears and the assistant does not, the UI path is working. The next place to inspect is the AG-UI event stream.
The backend must emit at least:
If TEXT_MESSAGE_CONTENT uses a different messageId than TEXT_MESSAGE_START, the reducer cannot append content to the message.
#Loading never stops
The adapter sets isLoading to true on RUN_STARTED.
It sets isLoading back to false on:
RUN_FINISHEDRUN_ERRORonRunFailed
If loading never stops, your backend likely did not emit a terminal event or the AG-UI source did not report a failure.
#Errors are not visible
Protocol errors should come through RUN_ERROR.
Transport or runtime failures may arrive through the AG-UI subscriber onRunFailed callback. The adapter stores that thrown value in agent.error() and sets status to error.
Your UI still needs to render error state. The base chat composition handles common error display, but custom layouts should read:
#Tool call args are empty
TOOL_CALL_ARGS parses the event delta as JSON.
This works:
This becomes {}:
The current reducer replaces args with each parsed payload. It does not assemble partial JSON fragments across multiple TOOL_CALL_ARGS events. Emit complete JSON for each args event.
#Citations do not show up
Check three things:
- Citations must live under
state.citations. - The citation key must match the assistant message id.
- A
STATE_SNAPSHOTorSTATE_DELTAmust arrive after citation data is available.
Example:
If your backend sends citations before the message exists, send another state event after the message is created. See Citations.
#Stop does not cancel the run
agent.stop() calls source.abortRun().
Cancellation depends on the AG-UI source implementation. HttpAgent supports abort behavior. A custom AbstractAgent subclass needs to implement cancellation itself.
#Regenerate throws
regenerate(index) throws when:
- Another run is already loading.
- The target index is not an assistant message.
- There is no previous user message to rerun from.
Pass the index of the assistant message you want to replace, not the user message.
#Interrupts, subagents, or history do not work
Those flows are not implemented by the AG-UI adapter today.
Current scope is messages, status/loading/error, tool calls, state/custom events, reasoning messages, message snapshots, and citations from state.
Use @ngaf/langgraph for the richer LangGraph-specific surface, or write a custom adapter against the @ngaf/chat Agent contract if you need AG-UI plus product-specific behavior.
#Isolate with FakeAgent
When you are unsure whether the issue is UI wiring or backend events, swap in the fake provider:
If the UI works with FakeAgent, the Angular wiring is fine. Focus on the backend event stream.