currai
{ pricing: "/pricing", blog: "/blog", docs: "/docs" }
Sign In

Troubleshooting

Fix missing traces, authentication failures, empty costs, serverless flush issues, and OpenTelemetry ingestion problems.

Most Currai issues fall into a small set of buckets: the app never sent events, the events were sent with invalid credentials, the process exited before the buffer flushed, or the trace arrived without enough metadata to show cost and grouping correctly.

Trace does not appear

If a trace does not show up in the dashboard after a few seconds, check these in order:

  1. Confirm the code runs on the server, not in the browser.
  2. Confirm CURRAI_PUBLIC_KEY and CURRAI_SECRET_KEY exist in the runtime that is sending traces.
  3. Confirm the key pair belongs to the workspace you are viewing.
  4. Call await currai.flushAsync() in TypeScript or await currai.flush_async() in Python before a short-lived process exits.
  5. Check your SDK onError handler or server logs for 401, 403, network, or timeout errors.

Authentication fails

Currai uses a public/secret key pair scoped to a workspace. The public key starts with pk-lf- and the secret key starts with sk-lf-.

SymptomLikely causeFix
401 UnauthorizedMissing, swapped, revoked, or malformed keyCreate a new key in Settings -> API keys and update the server environment
Trace lands in the wrong workspaceKey pair belongs to another workspaceUse a key created in the workspace you are viewing
Works locally but not in productionProduction environment variables are missingAdd the keys to the deployment platform and redeploy

Do not expose the secret key to client-side code. Currai ingestion should run in backend routes, server actions, workers, cron jobs, or other trusted server-side runtimes.

Trace appears without a generation

A trace only shows the top-level request. A generation shows the model call inside that request. If the trace appears but the generation is missing:

  • Create the generation before the provider call.
  • Call generation.end() after the provider returns.
  • Make sure exceptions still end or update the observation before the request exits.
  • Flush after the generation update has been buffered.

For multi-step LLM flows, create spans for retrievers and tools, then nest generations under the trace or under those spans. See Nested traces.

Cost is empty

Currai computes cost from the generation model and token usage. If cost is empty, the generation usually lacks one of those fields.

Send:

  • model, for example gpt-4o-mini.
  • usage.input, the prompt/input token count.
  • usage.output, the completion/output token count.
  • usage.total, if your provider returns it.
  • usage.unit: "TOKENS".

If you use a custom or newly released model, token counts can still be recorded even when pricing is not yet mapped. In that case, cost may stay empty until a price is configured for that model.

Sessions or users are not grouped

Session and user grouping depends on stable ids. Pass the same sessionId for every trace in one conversation and the same userId for every trace from one end user.

For TypeScript, use camelCase:

const trace = currai.trace({
  name: "chat-turn",
  sessionId: "sess-1",
  userId: "user-1",
});

For Python, use snake_case:

trace = currai.trace(
    name="chat-turn",
    session_id="sess-1",
    user_id="user-1",
)

OpenTelemetry spans do not arrive

For OTLP ingestion, verify:

  • The endpoint is https://www.currai.app/api/public/otel/v1/traces.
  • The exporter uses OTLP/HTTP, not OTLP/gRPC.
  • The request includes HTTP Basic auth or Authorization: Bearer sk-lf-....
  • The payload is OTLP protobuf or OTLP JSON.
  • Model calls include gen_ai.request.model or another GenAI attribute so Currai can classify them as generations.

See OpenTelemetry for the full attribute mapping.

Duplicate traces

Duplicate traces usually come from constructing instrumentation more than once or retrying the same job without a stable id.

  • Create one Currai client per server process where possible.
  • Avoid registering the same OpenTelemetry processor/exporter multiple times.
  • In job runners, make sure retry logic does not replay the same completed trace unless that is intentional.

Still stuck

Send the trace name, approximate timestamp, SDK language, runtime, and any ingestion error to support@currai.app. Do not send secret keys, full prompts, completions, or user data unless you have intentionally redacted them.