Skip to content

fix(discord): keep default account online when adding named accounts#96401

Merged
steipete merged 2 commits into
openclaw:mainfrom
849261680:fix/92985-discord-default-secretref
Jul 6, 2026
Merged

fix(discord): keep default account online when adding named accounts#96401
steipete merged 2 commits into
openclaw:mainfrom
849261680:fix/92985-discord-default-secretref

Conversation

@849261680

@849261680 849261680 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Closes #92985

What Problem This Solves

Fixes an issue where users with a working default Discord account could take that account offline when adding a second named Discord account backed by SecretRefs. The default account's top-level token could remain unresolved in the active runtime snapshot, causing Discord startup to treat it as configured but unavailable and enter the restart loop reported in #92985.

Why This Change Was Made

Discord already treats a configured top-level token as an implicit default account even when named accounts exist. This change keeps that implicit-default handling inside the Discord secret contract so Discord SecretRef collection matches Discord account listing/runtime behavior without changing the public shared channel-secret helper signature. Sibling channel behavior remains unchanged.

User Impact

Adding a named Discord account no longer prevents the existing default account's file-backed SecretRef token from being materialized. Multi-account Discord gateways can keep the default account available while bringing up the additional account.

Evidence

  • pnpm install --frozen-lockfile
  • pnpm exec oxfmt --check --threads=1 extensions/discord/src/secret-config-contract.ts src/secrets/channel-secret-basic-runtime.ts src/secrets/runtime-discord-surface.test.ts
  • node scripts/run-oxlint.mjs extensions/discord/src/secret-config-contract.ts src/secrets/channel-secret-basic-runtime.ts src/secrets/runtime-discord-surface.test.ts
  • OPENCLAW_VITEST_FS_MODULE_CACHE_PATH=.vitest-cache-92985-private OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS=300000 node scripts/run-vitest.mjs src/secrets/runtime-discord-surface.test.ts src/secrets/runtime-telegram-token-inheritance.test.ts src/secrets/runtime-channel-inactive-variants.test.ts
    • 3 files passed, 22 tests passed
  • File-backed runtime proof with node --import tsx: prepared and activated a runtime snapshot with channels.discord.token and channels.discord.accounts.second.token both sourced from a JSON file SecretRef, then resolved Discord runtime accounts without printing token values.
    • snapshotWarnings: []
    • materializedConfig.topLevelTokenPresent: true
    • materializedConfig.secondTokenPresent: true
    • accounts.default.tokenStatus: available, tokenSource: config, tokenPresent: true
    • accounts.second.tokenStatus: available, tokenSource: config, tokenPresent: true
    • enabledAccounts: default, second
  • .agents/skills/autoreview/scripts/autoreview --mode local --prompt "Review the updated narrow fix for issue #92985 after moving implicit-default SecretRef handling behind the Discord-owned secret contract instead of changing the public shared helper signature. Focus on owner boundary, file-backed SecretRef proof shape, sibling channel behavior, and whether this remains minimal."
    • clean: no accepted/actionable findings

@849261680
849261680 requested a review from a team as a code owner June 24, 2026 12:21
@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord size: S labels Jun 24, 2026
@clawsweeper

clawsweeper Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed July 1, 2026, 7:02 PM ET / 23:02 UTC.

Summary
The PR adds Discord-only implicit default-account handling to the Discord SecretRef collection contract and adds a file-backed runtime snapshot regression test for default plus named accounts.

PR surface: Source +34, Tests +66. Total +100 across 2 files.

Reproducibility: yes. Source inspection shows current main can skip materializing channels.discord.token when explicit named accounts all provide tokens, while Discord still lists a configured top-level token as an implicit default account and fails closed if that token remains an unmaterialized SecretRef.

Review metrics: 1 noteworthy metric.

  • Discord SecretRef active surface: 1 implicit default-account path added. Maintainers should notice that top-level Discord token materialization now follows Discord runtime account listing when named accounts exist.

Stored data model
Persistent data-model change detected: serialized state: src/secrets/runtime-discord-surface.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #92985
Summary: This PR is the candidate fix for the open Discord hot-reload/default SecretRef issue; older Discord SecretRef reports overlap in mechanism but describe different paths or are closed.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🦞 diamond lobster
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Mantis proof suggestion
A real visible Discord transport proof would materially show the online/offline behavior after hot reload. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify a default Discord account stays online and can reply after adding a second named SecretRef-backed account.

Risk before merge

  • [P1] The PR intentionally changes Discord multi-account active-surface semantics: a configured top-level token remains active as the implicit default when named accounts exist, so stale or unresolvable top-level Discord SecretRefs may now fail startup instead of being ignored.

Maintainer options:

  1. Accept Discord implicit-default semantics (recommended)
    Maintainers can accept the compatibility risk because Discord already treats a configured top-level token as the default account at runtime.
  2. Require live hot-reload proof
    Maintainers can ask for a redacted Discord gateway hot-reload log showing the default account stays online after adding the named account.

Next step before merge

  • [P2] No automated code repair is indicated; the remaining action is maintainer review of the intentional Discord compatibility change and normal merge gates.

Security
Cleared: The diff changes TypeScript SecretRef collection logic and a focused test only; it adds no dependency, workflow, package, secret logging, or code-execution surface.

Review details

Best possible solution:

Land the Discord-owned SecretRef collector fix after maintainer acceptance of the compatibility change and normal merge gates.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection shows current main can skip materializing channels.discord.token when explicit named accounts all provide tokens, while Discord still lists a configured top-level token as an implicit default account and fails closed if that token remains an unmaterialized SecretRef.

Is this the best way to solve the issue?

Yes. The PR fixes the Discord-owned SecretRef collection boundary, matching a sibling Feishu precedent and avoiding both a shared helper signature change and a runtime token fallback.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against 6df7db9f9e49.

Label changes

Label changes:

  • add rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • remove rating: 🐚 platinum hermit: Current PR rating is rating: 🦞 diamond lobster, so this older rating label is no longer current.

Label justifications:

  • P1: The PR targets a linked P1 Discord regression where adding a named account can take the existing default account offline.
  • merge-risk: 🚨 compatibility: The diff changes Discord multi-account SecretRef activation so existing stale top-level token refs may fail startup instead of remaining inactive.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🦞 diamond lobster and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes copied live output from a node --import tsx file-backed runtime proof that materialized both default and second Discord account tokens without printing token values.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes copied live output from a node --import tsx file-backed runtime proof that materialized both default and second Discord account tokens without printing token values.
Evidence reviewed

PR surface:

Source +34, Tests +66. Total +100 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 38 4 +34
Tests 1 66 0 +66
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 104 4 +100

Acceptance criteria:

  • [P1] Contributor reported oxfmt, oxlint, focused Vitest SecretRef tests, runtime proof, and local autoreview; maintainers may request a live Discord hot-reload proof before merge.

What I checked:

Likely related people:

  • vincentkoc: History for the shared channel-secret helper includes the runtime helper split and narrowed SDK seam that this PR deliberately avoids changing publicly. (role: shared SecretRef seam contributor; confidence: high; commits: dfb6c9c92079, 78639eff76af; files: src/secrets/channel-secret-basic-runtime.ts, extensions/discord/src/secret-config-contract.ts)
  • steipete: Discord account history includes account config helper/refactor work and multi-account behavior adjacent to the implicit default account path. (role: recent adjacent Discord account-runtime contributor; confidence: medium; commits: 1275b9b8737c, c74a50e4f1ca, 05b8679c8bbd; files: extensions/discord/src/accounts.ts, extensions/discord/src/token.ts)
  • Takhoffman: History shows a focused default Discord runtime account fix on the central account-listing file. (role: default Discord account behavior contributor; confidence: medium; commits: c7875f193b9d; files: extensions/discord/src/accounts.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. labels Jun 24, 2026
@849261680
849261680 force-pushed the fix/92985-discord-default-secretref branch from ca2bdd6 to 4d73cca Compare June 24, 2026 12:46
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 24, 2026
@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. and removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. labels Jul 1, 2026
@steipete steipete self-assigned this Jul 6, 2026
@steipete
steipete force-pushed the fix/92985-discord-default-secretref branch 2 times, most recently from a534f6f to 12a8900 Compare July 6, 2026 15:50
@steipete
steipete force-pushed the fix/92985-discord-default-secretref branch from 12a8900 to 6b89308 Compare July 6, 2026 15:50
@steipete
steipete merged commit 8547682 into openclaw:main Jul 6, 2026
43 checks passed
@steipete

steipete commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Merged via squash.

github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 7, 2026
…penclaw#96401)

* fix(discord): keep default SecretRef active with named accounts

* fix(discord): align implicit default secret surfaces

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
giodl73-repo pushed a commit to giodl73-repo/openclaw that referenced this pull request Jul 8, 2026
…penclaw#96401)

* fix(discord): keep default SecretRef active with named accounts

* fix(discord): align implicit default secret surfaces

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Adding a second Discord account via hot-reload knocks the default account into a permanent auto-restart loop (entire Discord channel offline)

2 participants