Skip to main content
When something isn’t behaving as expected — spans not appearing, runs not completing, export not firing — debug mode prints a log line for every significant internal event so you can see exactly what’s happening.

Enabling Debug Mode

Code API
import { enableDebugMode, disableDebugMode } from "@uselemma/tracing";

enableDebugMode();
// ... run your agent ...
disableDebugMode(); // optional
Environment variable
LEMMA_DEBUG=true node your-app.js
Both methods can be used together. The env var is checked at call time, so you can set it after the module is imported.

What Gets Logged

All output is prefixed with [LEMMA:trace-wrapper] or [LEMMA:processor] so you can filter it easily.

wrapAgent / wrap_agent

EventWhen it fires
span startedA new root span is opened for a run, with agent name, run ID, and autoEndRoot value
span ended via onCompleteonComplete / on_complete was called and ended the span (only when autoEndRoot: false)
onComplete called but span not endedonComplete was called but autoEndRoot is active or the span was already ended
span auto-ended after fn returnedThe wrapped function returned and the span was ended automatically
span ended on errorAn uncaught exception ended the span, with the error message

RunBatchSpanProcessor

EventWhen it fires
onStart: top-level run spanA new ai.agent.run root span was started, with span ID, run ID, and whether auto-end is on
onStart: child spanA child span was started and attributed to a run
onEnd: span endedAny span ended, with span name, run ID, whether it’s the top-level span, and whether it was skipped for export
onEnd: direct child endedA direct child of a root span ended, with remaining child count
onEnd: triggering auto-end of top-level spanAll direct children finished and the root span is being auto-ended
exporting batchA batch of spans is being sent to the exporter, with run ID and span count
force_flush calledforceFlush was called
shutdown calledshutdown was called

Example Output

Running a simple agent with debug mode enabled produces output like this:
[LEMMA:trace-wrapper] span started { agentName: 'my-agent', runId: 'abc-123', autoEndRoot: true }
[LEMMA:processor] onStart: top-level run span { spanId: '...', runId: 'abc-123', autoEnd: true }
[LEMMA:processor] onStart: child span { spanName: 'gen_ai.chat', spanId: '...', runId: 'abc-123' }
[LEMMA:processor] onEnd: span ended { spanName: 'gen_ai.chat', spanId: '...', runId: 'abc-123', isTopLevel: false, skipped: false }
[LEMMA:trace-wrapper] span auto-ended after fn returned { runId: 'abc-123' }
[LEMMA:processor] onEnd: span ended { spanName: 'ai.agent.run', spanId: '...', runId: 'abc-123', isTopLevel: true, skipped: false }
[LEMMA:processor] exporting batch { runId: 'abc-123', spanCount: 2, force: false }

Common Issues

Run never appears in the dashboard

Symptom: Your agent runs successfully but no trace shows up. What to look for: Check whether exporting batch appears in the logs. If it does, the spans were sent and the issue is likely downstream (network, API key, or ingestion). If it doesn’t, work backwards through these checks:
  1. No onStart: top-level run spanregisterOTel was never called, or was called after the agent ran. Make sure registerOTel is called once at startup before any agent invocations.
  2. onStart: top-level run span appears but exporting batch never does — The root span was opened but the run batch never completed. This usually means the top-level span never ended:
    • With autoEndRoot: true (the default): check that span auto-ended after fn returned appears. If it doesn’t, the function may have thrown and the error path should show span ended on error.
    • With autoEndRoot: false: check that span ended via onComplete appears. If it doesn’t, onComplete was never called.
  3. exporting batch appears with spanCount: 1 — Only the root span was exported and no child spans. Child spans from frameworks like the Vercel AI SDK or OpenAI Agents SDK won’t appear unless their instrumentation is registered. See the integrations.

Spans appear but the run doesn’t close

Symptom: You see onStart lines for child spans, but exporting batch never fires and the run hangs open in the dashboard. What to look for: Check the remainingChildren value on onEnd: direct child ended lines. If it never reaches 0, a child span that was opened never ended — commonly a streaming span left open if an error is swallowed mid-stream.
[LEMMA:processor] onEnd: direct child ended { ..., remainingChildren: 1 }
[LEMMA:processor] onEnd: direct child ended { ..., remainingChildren: 1 }
# remainingChildren never hits 0 — one span is stuck open
The onEnd: triggering auto-end of top-level span line only fires once remainingChildren hits 0. If that line is missing, find the span that was started but never ended and ensure its lifecycle is closed (e.g. by awaiting the stream to completion or using a finally block).

Spans are started but not attributed to a run

Symptom: You see onStart: child span but no matching onStart: top-level run span before it. What to look for: The processor only attributes child spans to a run if it saw the parent run start first. This can happen if:
  • The child span is created outside the wrapAgent context (before or after the wrapped function executes)
  • The span’s parent context doesn’t trace back to an ai.agent.run span
Make sure all instrumented calls happen inside the wrapped function body.

skipped: true on a span

Symptom: A span appears in onEnd logs with skipped: true and is not included in the export batch. What to look for: The processor skips spans from the next.js instrumentation scope to avoid noise from framework internals. If you’re seeing unexpected spans skipped, check the spanName in the log — the span may be emitted by Next.js middleware or routing and is intentionally excluded.

Checking Debug Mode State

import { isDebugModeEnabled } from "@uselemma/tracing";

console.log(isDebugModeEnabled()); // true or false
Debug mode is off by default and intended for local troubleshooting. It writes directly to stdout — avoid leaving it enabled in production.