Dashboard Get started

Troubleshooting

Something not working? This page walks through the most common problems and exactly how to diagnose them from the terminal.

No spans appearing in the dashboard

This is the most common issue and almost always comes down to one of four things: wrong DSN, OTel not initialised, endpoint not reachable, or spans stuck in a batch not yet flushed.

1. Verify your DSN is correct

Your DSN starts with la_live_ and is 41 characters long. Find it in Settings → DSN. A wrong DSN returns a 401 from the ingest gateway.

bash
# Quick check — should return 202
curl -X POST https://la-ingest-gateway.lightarch.workers.dev/v1/traces \
  -H "x-la-dsn: la_live_YOUR_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{"resourceSpans":[]}'
# → 202 (even an empty payload confirms the DSN is valid)
If you get 401, double-check the DSN value. If you rotated it in Settings, update the OTEL_EXPORTER_OTLP_HEADERS env var in your app and restart.

2. OTel must be initialised before any imports

For Node.js with the auto-instrumentation approach, the NODE_OPTIONS env var handles this automatically. If you are manually calling sdk.start(), it must run before anything else in your entry point.

bash
# Good — NODE_OPTIONS registers the SDK before your app code loads
node --env-file=.env server.js

# If you used la init, your .env already has:
# NODE_OPTIONS=--require @opentelemetry/auto-instrumentations-node/register

3. Send a test span directly with curl

This bypasses your SDK entirely and confirms the gateway is receiving data.

bash
curl -X POST https://la-ingest-gateway.lightarch.workers.dev/v1/traces \
  -H "x-la-dsn: la_live_YOUR_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "resourceSpans": [{
      "resource": {
        "attributes": [
          {"key":"service.name","value":{"stringValue":"test-service"}},
          {"key":"deployment.environment","value":{"stringValue":"development"}}
        ]
      },
      "scopeSpans": [{
        "spans": [{
          "traceId":"0af7651916cd43dd8448eb211c80319c",
          "spanId":"b7ad6b7169203331",
          "name":"test-span",
          "startTimeUnixNano":"1700000000000000000",
          "endTimeUnixNano":"1700000001000000000",
          "status":{"code":1}
        }]
      }]
    }]
  }'
# → 202

Then check /app/logs for test-service. If it appears, your ingest is working and the problem is in your SDK setup.

4. Batch export delay

By default the OTel batch exporter waits up to 5 seconds or 512 spans before flushing. In short-lived scripts (like a one-shot Node.js file), spans may never flush before the process exits.

javascript
// Force flush before exit (if managing sdk manually)
await sdk.shutdown();
process.exit(0);
bash
# Or set a shorter export interval via env var:
OTEL_BSP_SCHEDULE_DELAY=1000 node --env-file=.env server.js

Logs page shows no results

Service name doesn't match

The service filter must exactly match service.name from your OTel resource attributes (case-sensitive). Check what names are indexed:

bash
la query "SELECT DISTINCT service FROM recent_spans ORDER BY service"

Time range too narrow

The default view shows the last 1 hour. If you sent spans more than an hour ago, expand the time range to 24h or 7d using the preset buttons in the FilterBar.

Hot index (D1) holds the last 48 hours. For older data, enable the "Include historical" toggle in the FilterBar to query cold storage in R2.

Severity filter excluded your spans

If you deselected INFO or DEBUG severity chips and your spans have those levels, they'll be hidden. Click "Reset" in the FilterBar to restore all defaults.

Live tail not connecting

The Live toggle opens a WebSocket connection to the query proxy. If it stays disconnected (grey dot), check the browser console for errors.

WebSocket blocked by corporate proxy

Some networks block wss:// connections. Symptoms: the dot flashes briefly then goes grey, and the browser console shows WebSocket connection failed. Solutions: use a personal hotspot to test, or ask your network admin to allow WebSocket to*.workers.dev.

Session expired

Sessions expire after 30 days. If the WebSocket returns 401, sign out and sign back in. The CLI: la login.

Metrics page shows no data

Metrics require the OTel metrics SDK — traces alone are not enough. If you used la init with the auto-instrumentation package, HTTP metrics are sent automatically for Express/Fastify apps. For custom metrics or other frameworks:

bash
npm install @opentelemetry/sdk-metrics
javascript
import { MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'
import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-http'

const exporter = new OTLPMetricExporter({
  url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT + '/v1/metrics',
  headers: { 'x-la-dsn': process.env.OTEL_EXPORTER_OTLP_HEADERS?.split('=')[1] ?? '' },
})
const provider = new MeterProvider({
  readers: [new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 10_000 })],
})
provider.register()

Verify metrics are arriving with a direct curl:

bash
curl -X POST https://la-ingest-gateway.lightarch.workers.dev/v1/metrics \
  -H "x-la-dsn: la_live_YOUR_TOKEN_HERE" \
  -H "Content-Type: application/json" \
  -d '{"resourceMetrics":[]}'
# → 202

Source map resolver returns null

The resolver matches by release tag. The release tag you pass to --release must exactly match the release you select in the resolver tool.

bash
# Confirm which releases are uploaded:
la query "SELECT DISTINCT release FROM sourcemap_cache ORDER BY release DESC"

# Or list via API:
curl https://la-dashboard-worker.lightarch.workers.dev/api/sourcemaps/releases \
  -H "Authorization: Bearer <session_token>"
Release tags are case-sensitive. v1.0.0 and V1.0.0 are different releases. Use a consistent tagging convention (e.g. always lowercase vprefix matching your git tags).

CLI not working after la login

Token not persisting

The CLI stores your token at ~/.config/lightarch/config.json (Linux/macOS) or %APPDATA%\lightarch\Config\config.json (Windows). If the directory is read-only or the CLI doesn't have write permission, the token won't persist.

bash
# Check stored token on Linux/macOS:
cat ~/.config/lightarch/config.json

# Re-authenticate:
la login

eo: command not found

bash
# Install globally:
npm install -g @lightarch/cli

# If npm's global bin isn't in PATH, use npx:
npx @lightarch/cli login

Getting 429 (Too Many Requests) or 402 on ingest

429 on /api/query — Query rate limit reached (10 requests/min per tenant). Wait 60 seconds and retry. Custom dashboards with many panels can hit this quickly — stagger panel loads or cache results.

402 on /v1/traces — Free tier 500 MB hard cap reached. Upgrade to Pro to continue ingesting. See pricing →

Still stuck?

Use the eo ask command or the AI chat widget in the dashboard to describe your issue. For ingest problems, include the HTTP status code and the output of:

bash
la query "SELECT service, severity, COUNT(*) as n, MAX(timestamp) as last_seen FROM recent_spans GROUP BY service, severity ORDER BY last_seen DESC LIMIT 20"

This shows exactly what's in your hot index and confirms whether any data has arrived at all. If you need hands-on help, open a support ticket from the chat widget in the dashboard.