Skip to Content
RiusSDKTroubleshooting

Troubleshooting

Symptoms first, causes second. Everything here assumes a current SDK: glassflow-rius 0.13.0 or newer for Python, @glassflow-ai/rius 0.4.0 or newer for TypeScript. Older releases behave the same on the basics, but some log lines quoted below were worded differently.

No traces are arriving

Check in this order:

  1. Is the SDK disabled? RIUS_DISABLED=1 (or true/yes/on) silently drops all spans in-process. Also check disabled=True in code.

  2. Is sampling set low? RIUS_SAMPLE_RATE=0.1 keeps one trace in ten; 0 keeps none. Sampling decides per whole trace, so a sampled-out trace is completely invisible, not partially.

  3. Did the process exit before the batch flushed? Batches flush every 5 seconds by default. Short scripts can exit between batches if the interpreter is killed rather than exiting cleanly; call client.flush() at the end. Serverless invocations should always flush explicitly. Since 0.9.0, flush() returning True confirms delivery, not just an empty queue: it returns False when the queue drained but the last export was rejected.

  4. Endpoint and key. Since 0.9.0 the SDK diagnoses these itself, as warnings on the rius.* loggers:

    • init() warns immediately when no API key is configured and the SDK would export to the managed platform.
    • A one-shot background connectivity check at init() warns when the endpoint rejects your key (HTTP 401/403, check RIUS_API_KEY) or cannot be reached at all (check RIUS_ENDPOINT).
    • The first failed export logs a warning saying traces are not being delivered; repeats log at DEBUG until an export succeeds, and recovery logs at INFO.

    If you see none of these, raise your log level; the SDK warns but never raises in your code.

”init() called again” warning

The global OpenTelemetry provider is write-once. A second init() returns the existing client unchanged and logs this warning. If you genuinely need to reconfigure, call client.shutdown() first; if you need a parallel pipeline, use init(set_global=False).

An instrumentation is not producing spans

  • The extra (Python) or optional package (TypeScript) must be installed in the same environment (pip install "glassflow-rius[openai]", or npm install @arizeai/openinference-instrumentation-openai). A requested-but-missing integration logs a warning at init() time.
  • The instrumented library must be installed too. In Python a missing one logs a DependencyConflict, see init() logs a DependencyConflict.
  • Scoped clients (set_global=False) do not auto-instrument; pass instruments=[...] explicitly.
  • If another OpenTelemetry setup already instrumented the library, the SDK leaves it alone by design; its spans go wherever that setup exports.
  • TypeScript, CommonJS apps: require the traced package before init(). The SDK patches the build of a provider or MCP SDK your process actually uses, so CommonJS and pure-ESM applications both get spans. The one pattern it cannot repair is a CommonJS require of openai, @anthropic-ai/sdk, or @modelcontextprotocol/sdk that happens only after init(): those calls stay untraced even though await client.ready lists the integration. Move the require above init(), where applications naturally place it, or trace the affected calls with manual generations. The langchain and vercel-ai integrations do not patch the package and have no ordering rule.

init() logs a DependencyConflict

DependencyConflict: requested: "anthropic >= 0.84.0" but found: "None"

The extra is installed but the library it instruments is not. Extras carry the instrumentation only, so glassflow-rius[anthropic] does not install anthropic. Rius takes no dependency on provider SDKs on purpose: pinning them would let an observability library dictate the version your model calls run against.

Install the library alongside the extra, and that integration starts working on the next init():

pip install "glassflow-rius[anthropic]" anthropic

The message comes from OpenTelemetry’s instrumentation base class, so it names the version range the instrumentation supports and None for what it found. Nothing else breaks: tracing continues, and only the integration whose library is missing stays off. If you meant not to have that library, drop the extra as well, or list the ones you want with init(instruments=[...]) so the SDK never tries the others.

Content is missing from spans

  • capture_content=False (or RIUS_CAPTURE_CONTENT=false) strips prompt/response content at export while keeping metadata. See Privacy controls for exactly which attributes are covered.
  • A masking callable that raises or returns None drops the affected attribute entirely, by design (fail closed), with a warning log.

Values look truncated

Inputs, outputs, and serialized objects are capped at 8192 characters, with an explicit …(truncated) suffix. This is a fixed safety limit on attribute size.

Spans are dropped under load

The in-memory queue holds 2048 spans by default; overflow is dropped with a warning. Raise OTEL_BSP_MAX_QUEUE_SIZE, or lower the volume with sampling. See Reliability for all batching knobs.

Next steps

Last updated on