---
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
token_estimate: 1880
---
# 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**: Close sessions when the job ends. 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.

## 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()`](https://amplitude.com/docs/sdks/agent-analytics/sdk#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](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. Refer to [Agent Analytics privacy modes](https://amplitude.com/docs/amplitude-ai/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](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).

## 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).

