subtext_url, opens that person’s real session, and walks the decisive moments with screenshots, the component tree, network, and console. LangSmith detects; Subtext diagnoses.
This guide assumes the Subtext capture snippet is installed and the
langsmith SDK is installed with tracing enabled (LANGSMITH_TRACING=true, LANGSMITH_API_KEY set), or that you run on LangSmith Deployment (formerly LangGraph Platform).Attach the session URL
LangSmith is the exception to Subtext’s flat-property convention. Most integrations attachsubtext_url as a top-level property on a user, session, or event record. A LangSmith run has no such column — its context lives in metadata, a dict attached at run-create time. Attach subtext_url there, nested under metadata, on the root run (the top of the trace) so anything reading the trace’s metadata sees it without walking every child run. Which surface you use depends on how your agent runs.
The URL itself originates in the browser. Capture it with FS('getSession', { format: 'url.now' }) — it returns null until the session has started, so read it after init (and re-read after a re-identify), then send it to your backend with the request that starts the agent run:
@traceable (Python decorator)
A static metadata= on the decorator is fixed at import time, which is no use for a per-end-user URL. Pass it per call instead, via langsmith_extra:
RunTree (manual instrumentation)
config.metadata (LangChain / LangGraph runnables)
The common case: your agent is a LangChain or LangGraph runnable invoked once per end-user request. Thread the session URL through the invoke config — the active LangChainTracer reads config["metadata"] and writes it onto the run automatically, no direct tracer call needed.
LangSmith Deployment (deployed assistants)
If your agent runs as a LangSmith Deployment, attach the same key in the run-create call’s top-levelmetadata field, whether from the SDK or REST directly. This is the surface a backend or proxy uses when it — not the browser — holds both the end-user’s session identity and the call that starts the agent run.
From signal to session
However you first hear about a bad run in LangSmith — a flagged trace, an eval regression, an error spike — the path is the same: get to thesubtext_url in the run’s metadata, then hand it to your agent for a Detect-vs-Diagnose read. If you land on a child run and don’t see it, jump to the root run, where it’s attached.
A trace flagged low-quality in the UI
A trace flagged low-quality in the UI
Scanning the traces table (or an annotation queue) in your LangSmith project, you spot a run someone tagged low-quality, or thumbs-downed from your product’s feedback widget.Open the run, go to the Metadata panel, and copy the
subtext_url value. If you’re on a child run and don’t see it, jump to the root run.An eval-dashboard regression
An eval-dashboard regression
An online evaluator’s score (say
answer_correctness, or your own review_quality feedback key) drops week-over-week on the LangSmith experiments dashboard.Filter the project’s runs by the low-scoring feedback key, open a handful of the worst-scoring runs, and copy subtext_url off each one’s metadata.An error spike on a chain
An error spike on a chain
A spike in errored runs on a specific chain or node — LangSmith’s own monitoring, or an Automation-driven Slack/webhook alert, flags it.Filter runs by
error for the affected chain in the window, open a few, and copy subtext_url off each.For agents
An autonomous agent can run the whole loop against LangSmith directly: discover the flagged runs, extract thesubtext_url from trace metadata, and hand each session to the Subtext MCP. LangChain ships an official MCP server, langsmith-mcp-server — run it locally over stdio (pip install langsmith-mcp-server or uvx langsmith-mcp-server) or in Docker, authenticated with LANGSMITH_API_KEY. Repo: github.com/langchain-ai/langsmith-mcp-server; docs: docs.langchain.com/langsmith/langsmith-mcp-server.
1
Discover flagged runs
With the MCP, See the trace query syntax reference for the full filter grammar.
fetch_runs is the discovery tool — fetch a trace tree by trace_id, filtering by error, run_type, or a raw FQL (Filter Query Language) query. Without the MCP, Client.list_runs takes the same FQL filter:2
Extract the session URL
Read
subtext_url off the flagged run’s root-run metadata. A run fetched from deep in the trace tree may not carry it, so walk up to the root run (no parent_run_id) if the child run you matched doesn’t have it:3
Hand off to Subtext
For each URL, call
review-open(session_url=<subtext_url>) on the Subtext MCP, then step through at the flagged moment for a Detect-vs-Diagnose read. Batch several runs’ URLs to review a spike or regression together for the common cause.subtext_url only round-trips if it was attached to the root run at trace-create time (see Attach the session URL). It’s metadata, not a top-level column, so discover by error, score, or feedback first, then read subtext_url off the result. Treat a missing value as “not instrumented,” not an error.Related
- Session Review overview — what your agent does once a session is open.
- Install the capture snippet — required before any session URL exists to attach.

