Applies to:
- Plan - Any
- Deployment - Any
- Use case - Restore missing Task, Sentiment, or Issues facet summaries when a custom or reconstructed trace does not use the conversation structure recognized by Braintrust's default Thread preprocessor.
Summary
When a built-in Task, Sentiment, or Issues facet processes traces but produces no matched facet summaries, check whether the Thread view contains the complete user and assistant conversation. If you send a custom or reconstructed trace that stores messages outside the recognized structure, Braintrust’s default Thread preprocessor cannot transform it into the complete message sequence used by Topics. Topics then receives incomplete context and can returnno_match even when the raw trace contains a clear signal. Adding a custom preprocessor requires fewer ingestion changes and can remain the project default. Alternatively, format model calls as llm spans with recognized input and output messages so the default preprocessor can reconstruct the conversation.
What is happening
Before running a Topics facet’s prompt, Braintrust preprocesses the trace into a formatted conversation. By default, facets use Braintrust’s built-in Thread preprocessor. If you create a custom preprocessor and set it as the project default, facets use it unless configured to use another preprocessor. Braintrust’s default Thread preprocessor readsinput and output from llm or untyped spans, converts recognized message formats into role/content pairs, and deduplicates messages across spans. A typical trace records the messages sent to the model on the LLM span’s input and the returned assistant message on its output.
Custom ingestion and post-processing pipelines do not always produce this structure. As a result, the default preprocessor may return an incomplete conversation, causing Topics to evaluate only part of the interaction.
An incomplete conversation can cause a facet to return its exclusion result even when the raw trace contains a clear signal:
- Sentiment results that start with
NEUTRALbecomeno_match. - Task or Issues results that start with
NONEbecomeno_match.
no_match are processed successfully, but they are excluded from the facet’s Matched count and from Topics clustering. This means the underlying problem is not necessarily the facet prompt or Topics automation. First confirm that the facet’s effective preprocessor returns the complete conversation. To check this, open a trace in Logs, select Thread, and confirm that the expected user and assistant messages appear.
Fix
Option 1: Add a custom Topics preprocessor
Use a custom preprocessor as a compatibility layer when you want to retain the existing trace structure. This is usually quicker than changing ingestion and is especially useful for pipelines that reconstruct traces after the model call or must preserve a custom schema. It can be a durable solution as long as you maintain and retest it when the source trace structure changes.- Go to Logs, open a representative trace, and select the Thread tab.
- Select the preprocessor picker, then select + Custom preprocessor.
- Add a preprocessor that explicitly transforms your root-span or custom trace fields into the complete conversation as an array of
role/contentmessages. For example, emit user turns frominput.messagesorturn_Nfields and assistant text fromoutput.answer. - Test the preprocessor against several representative traces. Confirm the Thread preview includes the complete user and assistant conversation, then save it with a clear name.
- Go to Settings > Advanced and select it under Default preprocessor. Topics facets use this default unless a facet explicitly selects another preprocessor.
- For traces that already contain
no_match, usebt topics rewindto replay the affected historical window through the Topics pipeline with the updated preprocessor. Newly processed traces use the updated project default automatically.
Option 2: Format traces for the default Thread preprocessor
If you control how traces are created, use the standard structure so Braintrust’s default preprocessor can transform them without project-specific logic:- Record each model call as an
llmspan. - Store the messages sent to the model on
inputasrole/contentobjects. - Store the returned response on
outputas an assistant message. - Test the trace with the built-in Thread preprocessor and confirm it reconstructs the complete user and assistant conversation.
How to confirm it worked
- In Logs, open representative traces and select Thread. Confirm that the selected preprocessor displays every expected user and assistant message.
- Open Scorers and test the affected Task, Sentiment, or Issues facet. Confirm a trace with a clear signal returns a usable facet summary rather than
no_match. - If you used a custom preprocessor, set it as the project default, then test the same trace again to confirm the facet uses it without a manual override.
- On Topics, open the affected facet’s menu and select View matched logs. Confirm that matched facet summaries now appear.
- Check the automation status after reprocessing. Topics needs at least 100 facet summaries before it can generate clusters for a facet.
Notes
- The
no_matchstatus is different fromSkipped.no_matchmeans the facet ran but its output matched the facet’s exclusion pattern.Skippedmeans the preprocessor did not return usable content. See Topics facets empty due to Skipped status for that troubleshooting path. - A legitimate neutral interaction or a trace with no identifiable task or issue can correctly return
no_match. Test with traces that contain an unambiguous signal before treating the result as an extraction problem. - Preprocessors are project-scoped. Configure the preprocessor separately in every project that uses the same reconstructed trace shape.
- A custom preprocessor is coupled to the trace schema. Retest the Thread view whenever the upstream API payload or reconstruction pipeline changes.
- A custom preprocessor does not need to be temporary. It can remain the project default when preserving the existing trace structure is preferable to changing ingestion.
- If multiple projects share the same reconstruction pipeline, maintain and test one common preprocessor implementation even though it must be configured separately in each project.