Trace health
Find and fix traces that were recorded incompletely, before judges grade them.
Judges can only grade what the trace recorded. If the root span never arrives, or a tool span has no output, a judge sees only part of the run. Trace health checks every incoming trace for recording problems like these. It says nothing about whether the agent did a good job.
The checks
| Check | Fails when | Fix |
|---|---|---|
| Root span exists | The trace has no span without a parent. | Emit one parentless span for the top-level operation. Without it the trace never finalizes and is never evaluated. |
| Trace has one root | The trace has more than one root span. | Make child work inherit the active span context. Usually broken context propagation. |
| Spans have valid timing | A span has no real start time or a non-positive duration. | Start the span when work begins and end it after the work completes. |
| Parent spans exist | A span’s parent is not in the trace. | Propagate the active context; don’t reuse parent IDs from another trace. |
| Parents contain child timing | A child starts before or ends after its parent. | End the parent only after its children finish. |
| Applicable spans have input | A successful LLM, tool, function, agent, or generator span has no judgment.input. |
Record the input. Agent judges read span input. |
| Applicable spans have output | The same spans have no judgment.output. |
Record the output, or judgment.llm.tool_calls when a model answers with tool calls. |
| Spans have a consistent session ID | At least one span in the trace has a session ID, and another span has a different one or none. | Set the session on the root and let it propagate to every span. |
| LLM spans identify their model | An LLM span has no judgment.llm.model. |
Record the model name. |
| LLM spans have valid usage | Token counts are missing, negative, or not finite. | Record non-cached input and output tokens. |
| LLM spans have valid cost | judgment.usage.total_cost_usd is missing, negative, or not finite. |
Record provider, model, and tokens so ingest can price the call and write the cost, or record a real total_cost_usd. |
Each check applies only to traces that can fail it. The input check, for example, only counts traces with successful LLM, tool, function, agent, or generator spans, and the model, usage, and cost checks only count successful LLM spans. A check that applied to no traces in the selected range is listed as not applying, not as passing.
Conversation view checks
A second group of checks covers whether LLM calls can display as readable chat threads in the Conversation view. These only change how LLM calls display. Traces and evals work either way.
| Check | Fails when | Fix |
|---|---|---|
| Conversation input uses structured messages | An LLM span’s input is a flattened prompt string, so it shows as raw text. | Record judgment.input as structured messages with roles and content rather than a flattened string. |
| Conversation payload formats are supported | An LLM span’s input or output uses a structure or content block the Conversation view can’t read, so some content shows as raw data. | Record input as structured messages with role and content, and output as plain text or structured messages. Use supported content blocks: text, images, reasoning, tool calls, or tool results. |
| Recognized conversation content is meaningful | A recognized input or output has blank strings or empty message containers, so parts of the conversation show up blank. | Replace blank strings or empty message containers with real content. |
Where it shows up
- On the monitoring pages, such as Traces, the toolbar shows a badge for the past 24 hours. Its states are listed below.
- On the project home, a Trace health needs attention or Conversation view compatibility needs attention row appears when checks are failing.
- On a single trace, the Trace Health indicator in the trace header lists that trace’s issues, then its Passed and Not applicable checks, scoped to the trace or to individual spans.
- Over MCP,
get_trace_health_summary,list_trace_health_failures, andget_trace_healthreturn the same results to a coding agent. Passcategory: "conversation_view"for the Conversation view checks. See MCP tools.
| Badge | Shows when |
|---|---|
| Healthy | Both the tracing and Conversation view checks pass. |
| Tracing needs fixes | A tracing check fails. |
| Conversation View limited | Only Conversation view checks fail. |
| Trace health, Conversation view compatibility, or Not evaluated, for each group | None of the states above apply. |
| unavailable | The checks fail to load. unavailable is neither a pass nor a fail. |
Select Tracing needs fixes or Conversation View limited for a short summary, such as Fix 2 tracing problems. The summary has a fix prompt to copy or open in your coding agent, and View breakdown to open the full checks.
Fix a failing check
- Open the checks from the toolbar badge. The Trace health dialog has a Tracing tab and a Conversation view tab, and a time range selector (1h, 12h, 24h, 7d or 30d). The default is the past 24 hours; widen it if your change is older.
- Read the failing checks. They are grouped by what they affect, Affects evals or Affects cost tracking. Expand a check to read its fix, which starts with Fix:.
- Select View traces and open a few affected traces. Compare several before assuming one cause.
- Fix the instrumentation yourself, or hand it to a coding agent: copy the check’s prompt, or use Open in at the top of the dialog to open a prompt for the failing checks in your coding agent. The prompt tells the agent to call
list_trace_health_failuresandget_trace_healthover MCP before changing code. It doesn’t change your code by itself. - Send new traffic through the fixed path, open a new trace, and check its indicator.
Existing traces keep their recorded data, so older failures stay in the window until it moves past them.
Common causes
| Symptom | Likely cause |
|---|---|
| Root span doesn’t exist | An upstream service propagates traceparent but doesn’t export to Judgment, or the root ended after the process exited. See Ingest contract. |
| Multiple roots for one request | Context lost across a thread pool, queue, or service hop. See Tracing patterns. |
| Missing output on a model span | The model call isn’t wrapped and no integration recorded it. See Integrations. |
| LLM spans missing model, usage, or cost | A custom or subprocess model call without recordLLMMetadata, or attributes under keys Judgment doesn’t map. Add a mapper. |
| Inconsistent session IDs | Session set on child spans instead of the root, set to different values per service, or set partway through a run, so spans that ended earlier have no session ID. |