---
title: Troubleshoot Agent Analytics setup
description: "Fix common Agent Analytics instrumentation problems: missing Session Records, events that don't group into sessions, empty message content, missing costs, and split sessions."
product: general
lang: en
last_updated: 2026-10-14
token_estimate: 2795
---
# Troubleshoot Agent Analytics setup

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

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](https://amplitude.com/docs/amplitude-ai/agent-analytics/verify).

## 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](https://amplitude.com/docs/amplitude-ai/agent-analytics/sessions#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-ai-sdk#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()`](https://amplitude.com/docs/sdks/agent-analytics/sdk#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](https://amplitude.com/docs/sdks/agent-analytics/sdk#edge-runtimes-and-cloudflare-workers), or [send events without the AI SDK](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-http-api).

## 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](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-ai-sdk#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/sessions#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-opentelemetry#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/configure-session-timeouts). If a streamed response outlives the session, keep the session open until the stream is consumed. Refer to [Stream responses](https://amplitude.com/docs/sdks/agent-analytics/sdk#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/sessions#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](https://amplitude.com/docs/amplitude-ai/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](https://amplitude.com/docs/sdks/agent-analytics/sdk#manage-cost-and-tokens).

For how cost works, refer to [How cost is calculated](https://amplitude.com/docs/amplitude-ai/agent-analytics/taxonomy#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/verify).

## 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](https://amplitude.com/docs/amplitude-ai/agent-analytics/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](https://amplitude.com/docs/sdks/agent-analytics/sdk#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-http-api#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](https://amplitude.com/docs/amplitude-ai/agent-analytics/otlp-reference).

