> ## Documentation Index
> Fetch the complete documentation index at: https://docs.braintrust.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Thread view span extraction and filtering

> [!NOTE]
>
> **Applies to:**
>
> * Plan - Any
> * Deployment - Any
> *
> *

## Summary

**Goal:** Understand which spans appear in the trace Thread view and how the preprocessor selection affects extraction.

## Thread view preprocessor modes

The Thread tab's preprocessor picker controls how spans become a conversation:

* **Default**: The Thread view walks the trace and shows the root span, LLM-typed spans, and facet-typed spans inline. Score-typed spans render in a separate block. No preprocessor function runs and no cross-span deduplication happens.
* **Thread**: The built-in Thread preprocessor runs across every non-scorer span in the trace, extracts messages from `input` and `output`, and deduplicates across spans. This is the same preprocessor [Topics uses by default](https://docs.braintrust.dev/observe/topics/enable.md).
* **Custom preprocessor**: A saved JavaScript function runs on each span and returns the message array the Thread view renders. Output that isn't a recognized message array is converted to text, which the Thread view renders labeled with the preprocessor's name instead of a role. See [Write a custom preprocessor](https://docs.braintrust.dev/observe/topics/enable.md#write-a-custom-preprocessor).

These modes apply to the original thread view. The [new thread view](https://docs.braintrust.dev/observe/examine-traces.md#use-the-new-thread-view), which is the default, doesn't show the preprocessor picker and ignores the project's default preprocessor. It renders every trace in its own turn-based format. To choose a preprocessor, select  and choose **Go back to old thread view**.

## Span type attribution (Default mode)

To make a span appear in **Default** mode, set `span_attributes.type` to `"llm"` or `"facet"`:

```python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import braintrust

with braintrust.start_span(span_attributes={"type": "llm"}):
    result = client.chat.completions.create(...)
```

Score-typed spans (`type="score"`) render in a separate scorer block, not inline with the conversation.

When a trace has no LLM spans, **Default** mode renders any recognized user messages from the root span and any failed task-span errors in place of LLM content. If at least one user message renders, a **No LLM spans were recorded for this thread** notice with a **View spans** action follows it. A rendered task error appears without that notice, and when nothing renders at all the Thread view shows a **No LLM spans to display** empty state with the same **View spans** action. The built-in **Thread** and **Custom preprocessor** modes don't use this fallback: they render their own output or a **Preprocessor returned no messages** empty state.

## Format requirements

Both modes extract messages from each span's `input` and `output`. The fields must match a recognized shape: OpenAI-style role/content arrays, single message objects, content-parts arrays, plain strings, provider payloads (OpenAI, Anthropic, Google Gemini, Bedrock), framework formats (Vercel AI SDK, Pydantic AI, LangChain), or one of the wrapper keys `messages`, `prompt`, `input`, `output`, `choices`, `result`, `response`. For the full list and how to adapt traces that don't render, see [When traces don't work](https://docs.braintrust.dev/observe/topics/enable.md#when-traces-dont-work).

## Custom trace views

For span selection beyond what preprocessors can do, build a [custom trace view](https://docs.braintrust.dev/annotate/custom-views.md). Custom views receive the full trace JSON and can extract fields from any span.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.