langchain-ai/langchain · error · TracerException

No indexed run ID {run_id}.

Error message

No indexed run ID {run_id}.

What it means

BaseTracer keeps an in-memory run_map of runs it started. _get_run looks up a run_id in that map; an unknown id means on_llm_end/on_chain_end/on_tool_end (or similar) was called for a run this tracer never saw begin — a lifecycle mismatch — and raises TracerException.

Source

Thrown at libs/core/langchain_core/tracers/core.py:156

                        "Parent run %s not found for run %s. Treating as a root run.",
                        run.parent_run_id,
                        run.id,
                    )
                run.parent_run_id = None
                run.trace_id = run.id
                run.dotted_order = current_dotted_order
        else:
            run.trace_id = run.id
            run.dotted_order = current_dotted_order
        self.order_map[run.id] = (run.trace_id, run.dotted_order)
        self.run_map[str(run.id)] = run

    def _get_run(self, run_id: UUID, run_type: str | set[str] | None = None) -> Run:
        try:
            run = self.run_map[str(run_id)]
        except KeyError as exc:
            msg = f"No indexed run ID {run_id}."
            raise TracerException(msg) from exc

        if isinstance(run_type, str):
            run_types: set[str] | None = {run_type}
        else:
            run_types = run_type
        if run_types is not None and run.run_type not in run_types:
            msg = (
                f"Found {run.run_type} run at ID {run_id}, "
                f"but expected {run_types} run."
            )
            raise TracerException(msg)
        return run

    def _create_chat_model_run(
        self,
        serialized: dict[str, Any],
        messages: list[list[BaseMessage]],
        run_id: UUID,

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Ensure the same tracer/handler receives both the start and end events for every run_id
  2. Attach callbacks at the root invocation (e.g., invoke(..., config={'callbacks': [handler]})) rather than mid-stream
  3. In custom handlers, guard: if str(run_id) not in tracer.run_map: return before calling _get_run

Example fix

# before
class MyTracer(BaseTracer):
    def on_tool_end(self, output, *, run_id, **kw):
        run = self._get_run(run_id, "tool")   # TracerException if start was missed

# after
class MyTracer(BaseTracer):
    def on_tool_end(self, output, *, run_id, **kw):
        if str(run_id) not in self.run_map:    # skip runs we never started
            return
        run = self._get_run(run_id, "tool")
Defensive patterns

Strategy: try-catch

Validate before calling

def tracer_has_run(tracer, run_id) -> bool:
    return str(run_id) in tracer.run_map

class SafeTracer(BaseTracer):
    def on_tool_end(self, output, *, run_id, **kw):
        if not tracer_has_run(self, run_id):
            return  # run started elsewhere; skip silently
        run = self._get_run(run_id, "tool")

Try / catch

from langchain_core.tracers import TracerException

try:
    run = tracer._get_run(run_id, "tool")
except TracerException:
    return  # tolerate out-of-lifecycle events from foreign callbacks

Prevention

When it happens

Trigger: Calling callback handler end events with a fabricated or foreign run_id; a tracer attached mid-run so it missed on_*_start; reusing a run_id after the tracer was reset; concurrent tracers receiving each other's events.

Common situations: Custom callback managers or manual tracer event forwarding; multiprocessing/streaming setups where start events bypass one handler; calling .end() twice with different handlers.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/3682651e154a3594. Report an issue: GitHub.