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 call injectAgent(), the agent must have been provided via provideAgent() 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 appends each event delta to the tool call's accumulated argument buffer. When the accumulated buffer is valid JSON, the reducer stores the parsed object as the current args.
This can arrive as one complete payload:
Or as fragments:
While the buffer is incomplete, the previously parsed args remain in place. If the final buffer still cannot be parsed at TOOL_CALL_END, the adapter leaves the last-good parsed args instead of throwing.
#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.
#History or time-travel does not work
History and time-travel 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, interrupts from CUSTOM on_interrupt events, subagent/activity progress from ACTIVITY_* events, and citations from state.
Use @threadplane/langgraph if you need LangGraph Platform thread history APIs, or write a custom adapter against the @threadplane/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.