wrapAgent callback, every withSpan call attaches to the current run automatically via AsyncLocalStorage (Node) or contextvars (Python). Outside the callback — a different file, a worker, a queue handler, a separate service — that context doesn’t exist. You must pass the runId explicitly and call joinRun.
runId is the one compulsory extra parameter. Without it, spans have no run to attach to and are dropped.
Same process, different file
PassrunId as an argument. The receiving function wraps its work in joinRun(runId, fn), and every withSpan inside that wrapper attaches to the parent run.
- Node.js
- Python
Different service
runId travels over an HTTP header. The outbound side attaches it with propagationHeaders(); the inbound side reads it and calls joinRun.
- Node.js
- Python
joinRun reference
| Signature | What it does |
|---|---|
trodo.joinRun(runId, fn) (Node) | Runs fn with runId set as the active run. Every withSpan inside attaches to that run. Flushes spans on return. |
trodo.join_run(run_id) (Python, context manager) | Same, as a with block. |
joinRundoes not create a new run row. It only lets you emit spans against an existing run.- Calling
joinRunwith arunIdthat doesn’t exist on your site is a no-op — the spans are dropped silently. - If you want a separate run linked to a parent, use
wrapAgentwithparentRunIdinstead. See Recipes → Sub-agents.