Troubleshooting
Symptom → cause → fix for the most common Radicas SDK connection and data problems.
init(validate=True) (the default) already warns at startup when the endpoint is unreachable —
start there: the warning names the mode, protocol, and the most likely causes. For everything
else:
| Symptom | Likely cause | Fix |
|---|---|---|
| No spans at all in Radicas | Process exited before the batch exporter flushed (bounded runs are short) | Call radicas.shutdown() at the end of the run (atexit usually covers normal exits, but not os._exit, crashes, or some notebook kernels) |
| No spans, agent still running | Wrong endpoint or collector not up | LOCAL: is a local OTLP collector running on :4317? Check the init log line for the resolved endpoint; override with RADICAS_ENDPOINT |
Exporter logs 401 / unauthenticated | Missing, revoked, or malformed API key | Check RADICAS_API_KEY (no quotes/whitespace); rotate the key in the console if revoked. Remember the key is shown once at onboarding |
| Exporter logs connection refused on 4317 | gRPC protocol against an HTTP-only endpoint (or vice versa) | Match RADICAS_PROTOCOL to the endpoint: grpc → port 4317, http/protobuf → port 4318 / https endpoints |
| Timeouts only in CI / corporate network | Egress proxy in the way | Set HTTPS_PROXY/NO_PROXY appropriately; prefer http/protobuf, which honors standard proxy env vars better than gRPC |
| Spans arrive but land far in the past/future | Host clock skew | Sync the host clock (NTP); OTLP timestamps are client-generated |
invoke_agent spans have feature default | No feature configured | Set init(feature=...) / RADICAS_FEATURE, or scope with radicas.feature(...) (feature tagging) |
| Feature override not applied in a worker thread | Raw threading.Thread does not inherit OTel context | Attach a captured context in the worker — see the propagation section in feature tagging |
| Model shows as "unpriced" in the dashboard | The model id is not in the price book | Add the model (and its rates) to the price book; cost is estimated only for known models — the spans themselves are fine |
LLM spans have no tokens/model (llm.* source) | Framework not recognized — normalization did not fire | Check the span's scope name vs the support matrix; is the strategy activated? (init logs instrumented=...). File the framework for a deep-dive if unmapped |
MissingInstrumentorError at init | Framework detected but its instrumentor extra is not installed | Install the extra named in the error, e.g. pip install "radicas[langchain]" |
RadicasConnectionError raised at init | You set validate="strict" and the endpoint is unreachable | Fix connectivity (rows above) — or use the default validate=True to warn instead of raise |
Second radicas.init() seems ignored | By design — init is idempotent | Configure everything in the first call; restart the process to reconfigure |
| Content/prompt events missing | Content capture is opt-in and off by default | init(capture_content=True) — and note content rides the logs signal, not span attributes |
Warning: logs signal unavailable | OTel logs API/SDK version mismatch | Traces/metrics still work; align opentelemetry-sdk versions if you need content events |
Still stuck? The init log line
(radicas telemetry ready: service=... mode=... protocol=... endpoint=...) states exactly
what the SDK resolved — compare it against what you intended, then check the exporter's own
warnings in your process logs.
Telemetry reference
The canonical contract the SDK emits — span tree, full attribute table including token and cache-token usage, content events, and what Radicas computes from each field.
Migrating from radicas_otel
Move from the bench's setup_telemetry() connection layer to radicas.init() — a mapping table and what you gain.