> ## Documentation Index
> Fetch the complete documentation index at: https://glassray.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# SDK troubleshooting

> No traces appearing? Work down this checklist - key validity, source state, filters, sampling, serverless flushing, and the SDK's own diagnostics.

The SDK is fail-open by design: when something is wrong it warns and keeps your agent running, so "no traces appearing" is the symptom for everything. Work down this list - it's ordered by how often each one is the cause.

<Steps>
  <Step title="Turn on the SDK's diagnostics" icon="bug">
    ```sh theme={null}
    export GLASSRAY_DEBUG=true
    ```

    The SDK logs queue activity, transport results, and drop reasons. Most problems name themselves here - an auth failure, a muted sender, or a config warning appears immediately. (If you set `onWarn`, warnings go there instead of the console.)
  </Step>

  <Step title="Check the drop counters" icon="calculator">
    ```ts theme={null}
    console.log(glassray.stats()); // { sent, dropped: { byReason }, queued }
    ```

    * `sent: 0, queued > 0` - traces are waiting; on serverless this means a missing flush (next step).
    * `dropped.byReason` names the problem: `auth` means a key issue (invalid or missing `traces:write`), `queue_overflow` means the endpoint is unreachable and the bounded queue rolled over, `retry_exhausted` means the endpoint kept failing, `disabled` means the SDK never had a usable key/endpoint to begin with.
    * All zeros - no trace was ever produced: tracing is disabled or sampled out (below), or your wrap point never runs.
  </Step>

  <Step title="Serverless: are you flushing?" icon="cloud">
    A trace POSTs when its root settles - but Vercel, Lambda, and Workers can freeze the process right after your response, before the request leaves. Add the one-liner for your platform from the [serverless matrix](/sdk-reliability#serverless).
  </Step>

  <Step title="Is the key present and valid?" icon="key">
    `GLASSRAY_API_KEY` must be set in the environment your agent actually runs in (not just your shell). The server's answer tells you which problem you have:

    * **`401`** - the key is missing, malformed, or was revoked. Re-check the env var; if the key is lost, rotate it from the source's Configure dialog (keys are shown once and stored hashed).
    * **`403`** - the key is real but can't write: it lacks the `traces:write` permission, the source is **disabled**, or ingestion is suspended for the organization.

    On `401`/`403` the SDK warns **once and then mutes** - fix the key, then restart the process.
  </Step>

  <Step title="Is the source enabled?" icon="plug">
    In **Settings → Sources**, confirm the OTLP source you minted the key for is still there and enabled. A disabled source rejects writes with `403`.
  </Step>

  <Step title="Do the source's filters drop your traces?" icon="filter">
    A source can carry [ingest filters](/traces) that admit only matching trace names - non-matching traces are dropped at ingest, silently and by design. The server still returns `200` for them, so the SDK counts them as sent. Check the source's filter rules against the names you pass to `glassray.trace(name, …)`.
  </Step>

  <Step title="Is tracing disabled or sampled out?" icon="toggle-off">
    * `GLASSRAY_TRACING=false` anywhere in the environment is the kill switch - every handle becomes a no-op.
    * `enabled: false` in the constructor does the same.
    * A low `sampleRate` / `GLASSRAY_SAMPLE_RATE` drops whole traces by design - set it to `1` while debugging.
  </Step>
</Steps>

<Tip>
  Still stuck? Verify the endpoint itself with a raw request - the [OTLP ingestion page](/otlp-ingestion) documents the full error-code taxonomy (`400`/`401`/`403`/`413`/`415`/`503`), and a `curl` with your key isolates the SDK from the network path.
</Tip>
