CloudLine
Troubleshooting

No data showing

Your bot is running fine, but the dashboard says "—" or the status stays grey. Walk this checklist top-to-bottom.

The most common operator issue. The bot is up locally, but the CloudLine dashboard shows grey status and in every metric tile. Run through this checklist in order — each step is a different cause, ordered from most-common to least-common.

1. Are heartbeats reaching CloudLine at all?

Look at your bot's stdout / process logs. The SDK is intentionally quiet on success — it only logs when something fails. The four messages it can emit are:

CloudLine: heartbeat rejected (401) — check botId/secret
CloudLine: heartbeat HTTP <code>
CloudLine: heartbeat network error <…>
CloudLine: global fetch unavailable — Node 18+ required (or polyfill fetch)

If you see any of these, the problem is on the network side — see the matching section below.

If you see none of these and the status is still grey, the SDK isn't running at all. Go to step 4.

2. 401 — check botId/secret

The most-common cause. Your bot is talking to CloudLine, but the secret is wrong.

Run through these in order:

  1. Did you rotate the secret on the dashboard recently? The new value invalidates the old one immediately. You must redeploy with the new value.
  2. Is the env var name right? The SDK reads whatever you pass to it; if you wrote process.env.CLOUDLINE_TOKEN and the var is CLOUDLINE_SECRET, the SDK gets undefined and the request fails.
  3. Did you swap botId and secret? The botId is short (bot_…); the secret is long (clb_live_… + 32 chars). The SDK fails fast on missing fields, but it can't tell you swapped them.
  4. Is your env file actually being loaded? PM2, Docker, and systemd all have ways to strip .env files. Verify by adding a one-time console.log(process.env.CLOUDLINE_SECRET?.slice(0, 12)) near the start of your bot — you should see clb_live_…. Remove the log after you've confirmed.

3. heartbeat network error or HTTP 5xx

Your bot can't reach the CloudLine API:

  • Egress firewall on your host blocking outbound HTTPS to cloudline.kescohhtwitch.workers.dev. Some shared hosts default to deny-all egress except for whitelisted destinations.
  • DNS misconfigurationnslookup cloudline.kescohhtwitch.workers.dev from the host should resolve to a Cloudflare IP. If it doesn't, your DNS resolver is broken.
  • Transient outage on Cloudflare or our Worker5xx. The SDK retries twice automatically (250 ms, 500 ms). If it persists, check status.cloudflare.com.
  • TLS / certificate failure on a very old Node runtime. Node 18+ ships with a fresh CA bundle; older versions can fail TLS handshakes against modern Cloudflare endpoints.

4. Status stays grey, no SDK logs

The heartbeat loop isn't running. The most common reasons:

  • attach() ran after client.login() / bot.run(). Both block-or-block-equivalent. bot.run() in Python doesn't return until the bot stops, so any code after it is unreachable. The SDK never started.

  • attach() is in code that never executes. A condition was false, an import failed, an exception was swallowed. Add a console.log('cloudline attach') right after the call to confirm it runs.

  • You used the manual constructor (new CloudLine(…)) but never called .start(). Manual mode is opt-in. Either call start(), or use attach() for the one-line version.

  • You passed a bare discord.Client (Python) instead of commands.Bot. Bare clients have no add_listener, so the SDK can't hook events. The logger warns about this when it happens:

    CloudLine: client has no add_listener (bare discord.Client) — auto-start and command timing are disabled.

    Fix by switching to commands.Bot / AutoShardedBot, or by using manual mode.

5. Status goes green, but tiles show

The bot is heartbeating but not sending those specific metrics. Per-metric causes:

MetricTile shows because...
RAM / CPU (Python)You installed cloudline-bot without the [metrics] extra. psutil is missing. Run pip install "cloudline-bot[metrics]".
RAM / CPU (other runtimes)The runtime doesn't expose process.memoryUsage() or equivalents. The bot keeps working; the tile stays blank.
Slash p50 / p95No slash commands have been invoked yet in this heartbeat window. Trigger one. Percentiles are sampled-when-used, not polled.
Component p50 / p95Same — no button or select-menu interactions yet.
Autocomplete p50 / p95Same — autocomplete fires per keystroke. Type into a slash-command field that has autocomplete.
Latency (gateway ping)discord.js reports -1 before the first heartbeat ack; discord.py reports NaN. The SDK normalizes both to null until the gateway settles. Usually clears within the first 10–30 seconds.
Event-loop lag (Deno)Needs --unstable-node-builtins. Without it, perf_hooks isn't available.
ShardsSingle-process bots intentionally report null so the dashboard's sharded tile stays silent unless the bot is genuinely sharded.

6. Verifying the wire manually

When the SDK and logs aren't enough, send a hand-crafted heartbeat and see what the API says:

curl -X POST \
  -H "Authorization: Bearer clb_live_yoursecret…" \
  -H "Content-Type: application/json" \
  -d '{"seq":1,"sent_at":'$(date +%s%3N)'}' \
  https://cloudline.kescohhtwitch.workers.dev/api/bots/YOUR_BOT_ID/heartbeat

Possible responses:

  • 200 OK with empty body — the credentials are valid and the server accepted the heartbeat. Refresh the dashboard; the status should turn green within seconds. If it does, your local SDK setup is the problem (likely step 4).
  • 401 Unauthorized — the secret is wrong, the bot doesn't exist, or it belongs to a different user. The 401 is intentionally indistinguishable between those three to prevent enumeration. Re-check both the botId and the secret.
  • 429 Too Many Requests — you're rate-limited from this IP. Wait 60 seconds and try again. In production this only fires under abuse; if you're hitting it with a single manual curl, your IP is shared with a noisy neighbor.

Still stuck?

Drop into the Discord support channel with your bot ID (safe to share) and the SDK log line. The team usually replies within a few hours.