Troubleshooting
No data showing up
Aftertrace is up (you can open http://127.0.0.1:7311) but Sessions is empty.
- Confirm the receivers.
aftertrace servelogsOTLP gRPC 127.0.0.1:4317andOTLP HTTP 127.0.0.1:4318. If those ports failed to bind, serve exited. - Confirm Claude Code env. The keys must live in
~/.claude/settings.jsonor the shell, not in a repo.claude/settings.json. Claude Code ignores exporter variables there. See claude-code-setup.md. - Protocol must be set. Claude Code has no default
OTEL_EXPORTER_OTLP_PROTOCOL.grpcgoes to:4317.http/protobufandhttp/jsongo to:4318withOTEL_EXPORTER_OTLP_ENDPOINT=http://127.0.0.1:4318(no/v1/tracessuffix). - Traces need the beta flag.
CLAUDE_CODE_ENABLE_TELEMETRY=1alone is metrics (and logs if enabled). Waterfalls needCLAUDE_CODE_ENHANCED_TELEMETRY_BETA=1andOTEL_TRACES_EXPORTER=otlp. - Restart Claude Code after changing settings. Then send a prompt; metrics can take up to
OTEL_METRIC_EXPORT_INTERVAL(default 60s). - Check
/api/sessions. An empty array[]means ingest has not stored asession.id. claude --debug-file /tmp/claude-otel.log. Failures from your exporter are[3P telemetry].[Anthropic telemetry]is unrelated.- Managed settings can strip your endpoint. Detailed beta tracing (
ENABLE_BETA_TRACING_DETAILED+BETA_TRACING_ENDPOINT) redirects logs and traces away from the OTLP exporters. Unset that pair. - Behind a collector, Claude Code must still reach the collector, and the collector must export to Aftertrace's ports. behind-a-collector.md.
To prove the receivers without Claude Code, aftertrace demo or aftertrace import <dir> of synthetic JSONL. An OTLP client with the same OTEL_EXPORTER_OTLP_* values also works: http/protobuf to http://127.0.0.1:4318 posted traces to /v1/traces and they showed up under /api/sql.
Port in use
otlp grpc: listen tcp 127.0.0.1:4317: bind: address already in use
Something else (another aftertrace serve, a collector) holds 4317, 4318, or 7311. Pick other ports:
./aftertrace serve --db ./data/aftertrace.duckdb --grpc-port 14317 --http-port 14318 --ui-port 7312
Point Claude Code or the collector at the new gRPC/HTTP ports.
DuckDB lock
open db: ... Could not set lock on file "./data/aftertrace.duckdb": Conflicting lock is held in ... (PID ...)
Only one process opens a given DuckDB file. Stop the serve that holds it before demo or import on the same --db.
aftertrace import path
A directory that does not exist exits 1:
import: stat /tmp/does-not-exist-aftertrace: no such file or directory
An existing empty directory imports zero rows and exits 0. Check that traces.jsonl / logs.jsonl / metrics.jsonl are in that directory, JSONL, uncompressed. format: proto and zstd from the file exporter will not parse.
CGO build errors
imports github.com/duckdb/duckdb-go-bindings/lib/linux-amd64: build constraints exclude all Go files in ...
CGO_ENABLED is 0, or there is no C compiler, or you cross-compiled. go env CGO_ENABLED must print 1. Install a C toolchain (install.md). Do not set CGO_ENABLED=0. Cross-compilation needs CGO_ENABLED=1 and a CC for the target; the prebuilt DuckDB libs exist only for darwin/linux amd64+arm64 and windows-amd64.
On macOS, xcode-select --install. On Debian/Ubuntu, build-essential. On Windows, MinGW-w64 gcc.
Empty UI (stub page)
The page says "Aftertrace UI is not in this binary yet" and links /api/sessions.
web/dist/index.html is a committed stub so go test compiles without Node. go:embed takes whatever is on disk at go build. You need:
cd web && npm ci && npm run build:embed && cd ..
go build -o aftertrace ./cmd/aftertrace
npm run build (mocks on) is the wrong script for the binary. build:embed sets VITE_USE_MOCK=0. Rebuild after any UI change; embed is not live-reload.
npm run dev is a different loop: http://127.0.0.1:5173 with mock fixtures, no Go process. CONTRIBUTING.md.
Findings missing after demo
aftertrace demo prints them on stdout. The UI reads /api/findings from whatever --db serve opened. Serve the same path:
./aftertrace demo --db ./data/aftertrace.duckdb
./aftertrace serve --db ./data/aftertrace.duckdb
Default --db is $HOME/.aftertrace/aftertrace.duckdb, not ./data/aftertrace.duckdb.
Skill / MCP names are custom
Set OTEL_LOG_TOOL_DETAILS=1. Without it Claude Code redacts those names. Aftertrace stores what it is sent.
Prompt text in the UI
It should not be there. If it is, you passed --store-content and Claude Code has OTEL_LOG_USER_PROMPTS=1. Drop the flag and ingest new data; existing rows stay until you delete the DB (privacy.md).