On this page

For AI agents: a documentation index is available at /docs/llms.txt. Append .md to any page URL for markdown, or send Accept: text/markdown.

Troubleshoot Agent Analytics setup

Most Agent Analytics setup problems come from three causes: sessions that never close, events missing a required ID, or content sent in the wrong shape. Find your symptom below. To check a fresh instrumentation end to end, refer to Verify your Agent Analytics instrumentation.

Session Record events don't appear

Amplitude runs enrichment, and writes the [Agent] Session Record, only after a session closes.

  • The session hasn't closed yet: After an explicit close, the Session Record typically arrives within 15 to 20 minutes, and later during an enrichment backlog. Without an explicit close, the session waits for the idle timeout (30 minutes by default) plus up to about 15 minutes of ingestion.
  • Your code never sends Session End: Close sessions when the job ends. Refer to How sessions close.
  • The close event never left the process: With the AI SDK, a close buffered in memory is lost if the process restarts. Call ai.flush() after the close. Refer to Close and flush sessions.
  • Empty Session Records: Update to the latest AI SDK. Current releases create sessions only on real activity.

No events arrive

  • LLM calls run outside a session (AI SDK): Patched calls outside an active session context are dropped without an error. Wrap calls in session.run(), use the middleware, or refer to patch().
  • Wrong project: Confirm the API key belongs to the project where you enabled Agent Analytics, and check that project's Live Events.
  • node:async_hooks error in Cloudflare Workers: The full AI SDK can't bundle into a Worker. Use the fetch-based transport in Edge runtimes and Cloudflare Workers, or send events without the AI SDK.

Events return 200 but don't become sessions

The events are missing [Agent] Agent ID. The HTTP API acknowledges receipt before Agent Analytics processes the event, so a 200 doesn't mean the event grouped correctly. Set an agent ID on ai.agent(), or include [Agent] Agent ID on every event when you send to the HTTP API.

One conversation shows up as several sessions

  • A new agent per request: Constructing ai.agent(...) inside a request handler mints a new agent ID every turn. Define agents at module scope. Refer to Place agents and sessions on a long-lived server.
  • A new session ID per request or after a client idle timer: Thread one stable session ID through every turn of the job. Refer to Choose a session ID.
  • Every OpenTelemetry trace becomes its own session: Set a conversation attribute such as gen_ai.conversation.id. Without one, Amplitude falls back to the trace ID and marks the session degraded. Refer to Set session and user attributes.

Sessions close before the work is done

A long pause hit the idle timeout, so later turns arrived after enrichment ran and never reach the Session Record. Raise the timeout for jobs with long natural gaps. Refer to Configure session timeouts. If a streamed response outlives the session, keep the session open until the stream is consumed. Refer to Stream responses.

Users show as unknown or split into two

  • OpenTelemetry user is unknown: None of the user attributes Amplitude reads were set. Set enduser.id or another supported attribute.
  • One person appears as two users: A placeholder user ID, such as "anonymous", created a permanent separate user, or the backend generated a new device ID per request. Refer to Set user IDs.

The thread view shows no message content

  • $llm_message is a string: Send an object, { text: "..." }. Amplitude ignores a plain string without an error.
  • The message string is empty: The AI SDK drops an empty message instead of sending it. Check that the variable you pass is populated when you track it.
  • Your privacy mode strips content: metadata_only and customer_enriched never send message text. Refer to Agent Analytics privacy modes.

Cost is missing, zero, or too high

  • AI SDK, [Agent] Cost USD is missing or $0: The model name isn't in the pricing catalog, or it's a fine-tuned ft: model. Use the canonical provider model ID, or set totalCostUsd explicitly. Older SDK releases record $0, and current releases omit the property.
  • HTTP API or OpenTelemetry, cost is missing: Amplitude doesn't calculate cost for direct events. Send [Agent] Cost USD or gen_ai.usage.cost.
  • Session Cost USD is missing: If any event with token usage in the session has no cost, Amplitude omits the session total instead of reporting a partial one.
  • Session cost is too high: The server sums [Agent] Cost USD from every event, so a cost on a Tool Call or Session End inflates the total. Put cost only on AI Response.
  • Anthropic cache tokens don't match: Add cache_read_input_tokens and cache_creation_input_tokens to inputTokens. Refer to Manage cost and tokens.

For how cost works, refer to How cost is calculated.

Tool calls show 0 ms latency

patch() extracted the tool calls from message arrays, so it has no timing. Use tool() or trackToolCall() for real latency. Refer to Track tools.

Browser events drop without an error

setTransport('beacon') applies to the whole SDK permanently, so every later event sends once with no retry. Use the default transport. Refer to Browser and edge notes.

The OpenTelemetry Collector gets 413 or drops spans

  • 413: The request exceeded 4 MB decompressed or 2,000 translated events. Lower your Collector batch size.
  • 200 with partial_success: Ingestion rejected some events, and the 200 tells your Collector to delete the batch. Watch for the partial_success body.
  • Spans lost on restart: Use a persistent sending queue instead of an in-memory one.

Refer to OpenTelemetry ingestion reference.

Was this helpful?