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: Send it when the job ends, or wait for the idle timeout. 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.
  • Session End arrives after the timeout: Amplitude ignores a Session End that arrives after the idle timeout already closed the session. A high share of timeout in [Agent] Close Reason can mean your closes fire too late, for example only on page close.
  • The record is missing the last turns: Each session gets one Session Record. Amplitude stores events that arrive after the close but doesn't enrich them. If a session has no record at all and its last activity is well past the timeout, contact support with the session ID.

No events arrive

  • LLM calls run outside a session (AI SDK): The SDK drops patched calls outside an active session context without an error, and the LLM call itself still succeeds. This includes AMPLITUDE_AI_AUTO_PATCH=true, which patches at startup but opens no session, and background jobs, warm-up calls, and promises that escape the request scope. Wrap calls in session.run(), use the middleware, or refer to patch().
  • Events never leave the process: The SDK buffers events. Call flush() on shutdown, and per invocation in serverless functions and short-lived processes.
  • Wrong project: Confirm the API key belongs to the project where you enabled Agent Analytics, and check that project's Live Events.
  • Not sure whether it's instrumentation or delivery: Construct the client with debug: true to print every tracked event to stderr. If nothing prints, check your session context. If events print but don't arrive within a minute of flush(), check the API key and project.
  • 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, tool inputs and outputs, system prompts, exception messages, or stack traces. Refer to Agent Analytics privacy modes.
  • Placeholders such as [email] replace text: PII redaction is on. Redaction replaces matched patterns before events leave your process.
  • Streamed responses have no text: Drain the stream before the SDK records the response.

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. The usual cause is a model the SDK can't price, such as a nonstandard name, a gateway alias like openrouter/auto, or a fine-tuned ft: model. Fix the model ID or pass the cost on those calls; later sessions carry totals.
  • 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.

Verification fails early in setup

Expected. The verification gates check full instrumentation, including a real user ID, a real session ID, and an agent ID per component. With placeholder IDs or a minimal setup, the identity gates fail to show you what's left. Refer to Verify your Agent Analytics instrumentation.

Signal results are missing or look uninformative

  • No content reached Amplitude: In metadata_only or customer_enriched mode, or when your instrumentation sends empty strings, content-based signals have nothing to read. Amplitude leaves them unset instead of guessing, so they're absent rather than failed. Data Quality Issues still runs, and cost, latency, and error metrics still work. To measure quality without sending content, compute it yourself and send a Session Enrichment.
  • Sessions close mid-job: A half-session that hit the timeout reads as an incomplete conversation. Fix the idle timeout, then judge signal quality again.

For what each signal measures, refer to Agent Analytics built-in signals.

[Agent] Topic Classification stopped arriving

Amplitude no longer sends it. Topic and classification results land on [Agent] Evaluator Result (classification output) and in [Agent] Topic Summary on the Session Record. Move charts built on the old event to those properties.

Properties appear on events where they don't belong

The SDK writes [Agent] Provider and [Agent] Temperature only on AI Response and Embedding events. When they appear on Tool Call or User Message events, they came from your eventProperties, often a process-wide default set through ToolCallTracker.setAmplitude({ eventProperties }). Audit what you pass as eventProperties, and use context for custom segmentation dimensions.

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?