fix(bot): retry boot-time config fetch so bot self-heals on cold start #62

Merged
whitlocktech merged 1 commits from fix/bot-boot-config-retry into main 2026-07-15 19:17:25 +00:00
Member

Problem

After launching a new version or restarting the stack with docker compose, the Discord bot shows enabled but disconnected in the admin panel. The only workaround is to disable → save → re-enable → save, which forces the site to re-push config to the bot.

Root cause — a startup race

On docker compose up/restart the bot and app start together. The bot's depends_on: app uses condition: service_started, which only waits for the app container to launch — not for its internal Express server (port 3001) to be listening after it connects to the DB and boots.

bot/src/bootstrap.js did a single, un-retried fetch for the bot config. It loses that race (connection refused / non-ok), logs, and returns — the bot stays disconnected while the DB enabled flag is still true. Hence "enabled but disconnected." The manual toggle works only because it triggers a pushConfig from the (by-then-ready) site to the bot.

Fix

Retry the boot-time config fetch with backoff (~1 min, 2s apart) until the app answers:

  • Retry on network errors and 5xx (transient "app not ready yet").
  • Bail on 4xx — a real misconfig (e.g. bad internal key), not a startup race.
  • Once config arrives, reconnect if enabled, exactly as before.

Also wrapped discordManager.start(...) in try/catch: previously a bad-token boot would reject the bootstrap promise and crash the whole bot process (server.js exits on any start failure). Now it logs and stays running, waiting for the admin to fix config — consistent with the self-heal intent. The bot's own internal listener is already up before bootstrap() is awaited, so it stays reachable to the admin panel throughout the retry window.

Verification

No automated tests exist in the bot package, so this needs a runtime check. Cold whole-stack start with enabled=true in the DB:

docker compose down && docker compose up -d
docker compose logs -f bot

Expect a few boot-time config fetch not ready — retrying lines, then boot-time config says enabled — reconnectingdiscord client ready, with the admin panel showing connected without any toggling.

🤖 Generated with Claude Code

https://claude.ai/code/session_0114TpmrNW4wNXsHq5CR72jQ

## Problem After launching a new version or restarting the stack with `docker compose`, the Discord bot shows **enabled but disconnected** in the admin panel. The only workaround is to disable → save → re-enable → save, which forces the site to re-push config to the bot. ## Root cause — a startup race On `docker compose up`/restart the bot and app start together. The bot's `depends_on: app` uses `condition: service_started`, which only waits for the app **container** to launch — *not* for its internal Express server (port 3001) to be listening after it connects to the DB and boots. `bot/src/bootstrap.js` did a **single, un-retried** `fetch` for the bot config. It loses that race (connection refused / non-ok), logs, and returns — the bot stays disconnected while the DB `enabled` flag is still `true`. Hence "enabled but disconnected." The manual toggle works only because it triggers a `pushConfig` from the (by-then-ready) site to the bot. ## Fix Retry the boot-time config fetch with backoff (~1 min, 2s apart) until the app answers: - Retry on network errors and 5xx (transient "app not ready yet"). - Bail on 4xx — a real misconfig (e.g. bad internal key), not a startup race. - Once config arrives, reconnect if enabled, exactly as before. Also wrapped `discordManager.start(...)` in try/catch: previously a bad-token boot would reject the bootstrap promise and crash the whole bot process (`server.js` exits on any start failure). Now it logs and stays running, waiting for the admin to fix config — consistent with the self-heal intent. The bot's own internal listener is already up before `bootstrap()` is awaited, so it stays reachable to the admin panel throughout the retry window. ## Verification No automated tests exist in the bot package, so this needs a runtime check. Cold whole-stack start with `enabled=true` in the DB: ``` docker compose down && docker compose up -d docker compose logs -f bot ``` Expect a few `boot-time config fetch not ready — retrying` lines, then `boot-time config says enabled — reconnecting` → `discord client ready`, with the admin panel showing **connected** without any toggling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_0114TpmrNW4wNXsHq5CR72jQ
wtclaude added 1 commit 2026-07-15 14:39:51 +00:00
fix(bot): retry boot-time config fetch so bot self-heals on cold start
All checks were successful
PR Checks / server-tests (pull_request) Successful in 10m25s
PR Checks / client-build (pull_request) Successful in 9m53s
PR Checks / bot-install (pull_request) Successful in 10m0s
fc2554e5c3
On `docker compose up`/restart the bot and app start together. The bot's
`depends_on: app` uses `condition: service_started`, which only waits for the
app container to launch — not for its internal server (3001) to be listening
after it reaches the DB and boots Express. bootstrap.js did a single un-retried
fetch, lost that race, gave up, and left the bot disconnected while the DB
`enabled` flag stayed true — so the admin panel showed "enabled but
disconnected" until an admin toggled off/on to force a pushConfig.

Retry the boot config fetch with backoff (~1 min, 2s apart) until the app
answers: retry on network errors and 5xx, bail on 4xx (a real misconfig, not a
startup race). Also wrap discordManager.start in try/catch so a bad-token boot
logs and keeps the process alive instead of crashing it via server.js's
exit-on-start-failure.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0114TpmrNW4wNXsHq5CR72jQ
whitlocktech scheduled this pull request to auto merge when all checks succeed 2026-07-15 19:17:08 +00:00
whitlocktech approved these changes 2026-07-15 19:17:20 +00:00
whitlocktech merged commit e744723db2 into main 2026-07-15 19:17:25 +00:00
whitlocktech deleted branch fix/bot-boot-config-retry 2026-07-15 19:17:25 +00:00
Sign in to join this conversation.
No description provided.