Skip to content

[codex] Fix Discord SecretRef configured state#76429

Closed
rendrag-git wants to merge 1 commit intoopenclaw:mainfrom
rendrag-git:codex/discord-secretref-configured-unavailable
Closed

[codex] Fix Discord SecretRef configured state#76429
rendrag-git wants to merge 1 commit intoopenclaw:mainfrom
rendrag-git:codex/discord-secretref-configured-unavailable

Conversation

@rendrag-git
Copy link
Copy Markdown

@rendrag-git rendrag-git commented May 3, 2026

Summary

  • Problem: Discord config/status paths used strict token normalization, so unresolved SecretRef bot tokens threw before they could be represented as configured-but-unavailable.
  • Why it matters: SecretRef-backed Discord configs could fail read-only/status handling instead of showing the operator that the token is configured but unavailable.
  • What changed: Discord token resolution now carries tokenStatus, uses inspect-mode SecretRef handling for config/status paths, and reports configured_unavailable in snapshots.
  • What did NOT change (scope boundary): Runtime startup still requires an available token and will not start Discord with an unresolved/empty token.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: Discord token resolution used strict normalizeResolvedSecretInputString for unresolved SecretRef config values, which throws before read-only status/config paths can preserve configured credential metadata.
  • Missing detection / guardrail: Discord tests covered the strict throw behavior but did not cover the configured_unavailable status snapshot path for unresolved token SecretRefs.
  • Contributing context (if known): N/A

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: Discord token, client, shared plugin-base, and channel contract tests.
  • Scenario the test should lock in: unresolved Discord token SecretRefs report configured_unavailable in status snapshots while runtime startup remains gated on available tokens.
  • Why this is the smallest reliable guardrail: it exercises the token resolver and plugin config boundary where the incorrect strict behavior occurred.
  • Existing test that already covers this (if any): existing Discord SecretRef/action discovery tests covered adjacent read-only behavior.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

Discord status/config-only surfaces can now show a Discord bot token SecretRef as configured but unavailable instead of throwing during read-only token inspection. Runtime startup still requires a resolved token.

Diagram (if applicable)

Before:
[Discord token SecretRef unresolved] -> [strict token read] -> [throw]

After:
[Discord token SecretRef unresolved] -> [inspect token read] -> [configured_unavailable snapshot]
[Discord runtime startup] -> [requires available token] -> [does not start with empty token]

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) Yes
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) No
  • Data access scope changed? (Yes/No) No
  • If any Yes, explain risk + mitigation: SecretRef inspection now preserves configured_unavailable metadata without resolving or exposing secret values; runtime startup remains gated on an available token.

Repro + Verification

Environment

  • OS: Linux
  • Runtime/container: local source checkout
  • Model/provider: N/A
  • Integration/channel (if any): Discord
  • Relevant config (redacted): Discord token configured as SecretRef

Steps

  1. Configure channels.discord.token or channels.discord.accounts.<id>.token as an unresolved SecretRef.
  2. Build Discord account/status snapshot data.
  3. Attempt runtime startup without a resolved token.

Expected

  • Read-only/status paths report tokenStatus: "configured_unavailable".
  • Runtime startup/configured checks require an available token.

Actual

  • Before this change, strict normalization threw for unresolved Discord token SecretRefs.
  • After this change, status preserves configured_unavailable while startup remains unavailable until the token resolves.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: unresolved SecretRef token status, blank account token fallback behavior, client missing-token behavior, Discord extension suite, channel contracts, extension typechecks, changelog attribution.
  • Edge cases checked: account-scoped unresolved SecretRef, top-level unresolved SecretRef, explicit blank account token, runtime configured gating.
  • What you did not verify: full repo-wide pnpm build && pnpm check && pnpm test; live Discord network behavior for this exact branch.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes/No) Yes
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: Status may mark a token as configured even when the secret value is unavailable.
    • Mitigation: The snapshot includes tokenStatus: configured_unavailable, and runtime startup still requires tokenStatus: available.

AI-assisted: yes, prepared with Codex and locally reviewed.

@openclaw-barnacle openclaw-barnacle Bot added channel: discord Channel integration: discord size: S labels May 3, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 3, 2026

Codex review: needs maintainer review before merge.

Summary
The PR adds Discord tokenStatus propagation, inspect-mode SecretRef handling for Discord status/config paths, regression tests, and a changelog entry.

Reproducibility: yes. from source inspection: current main strictly normalizes Discord SecretRef token objects and then bases configured state on a resolved token string, so an unresolved configured ref cannot reach configured_unavailable status. I did not run tests because this review was required to stay read-only.

Next step before merge
The patch looks ready for normal PR review once the author marks it ready and exact-head validation runs; there is no narrow repair task left for an automated fix PR.

Security
Cleared: The diff changes Discord SecretRef inspection/status metadata and tests without adding dependency, workflow, package, network, permission, or secret-exposure surface.

Review details

Best possible solution:

Land this PR after it is marked ready and exact-head Discord/channel changed gates pass, keeping the fix inside the Discord plugin and existing credential-status contract.

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

Yes from source inspection: current main strictly normalizes Discord SecretRef token objects and then bases configured state on a resolved token string, so an unresolved configured ref cannot reach configured_unavailable status. I did not run tests because this review was required to stay read-only.

Is this the best way to solve the issue?

Yes. Inspect-mode SecretRef resolution plus tokenStatus propagation is the narrowest maintainable fix, and the force-pushed changelog entry addresses the prior process gap; the remaining blocker is draft/validation readiness, not patch design.

Acceptance criteria:

  • pnpm test extensions/discord/src/token.test.ts extensions/discord/src/shared.test.ts extensions/discord/src/client.test.ts extensions/discord/src/security-audit.test.ts
  • pnpm test extensions/discord/src/directory-contract.test.ts
  • pnpm check:changed in Testbox before merge if the PR is marked ready

What I checked:

  • Current main throws before status can represent unresolved SecretRefs: Discord token normalization on current main calls the strict normalizeResolvedSecretInputString helper, which throws for unresolved SecretRef values before read-only status/config paths can preserve credential metadata. (extensions/discord/src/token.ts:14, 6a3f5d0b1f35)
  • Current main derives configured from the resolved token string: Discord describeAccount/isConfigured currently use Boolean(account.token?.trim()), so an unresolved configured token ref is indistinguishable from a missing token after strict resolution fails or yields no value. (extensions/discord/src/shared.ts:152, 6a3f5d0b1f35)
  • Existing SecretRef contract supports inspect mode: resolveSecretInputString already returns configured_unavailable in inspect mode instead of throwing for unresolved SecretRefs, giving the PR a pre-existing contract to reuse. (src/config/types.secrets.ts:201, 6a3f5d0b1f35)
  • Existing status snapshot contract supports configured_unavailable: The shared account snapshot helper treats credential statuses other than missing as configured, including configured_unavailable. (src/channels/account-snapshot-fields.ts:58, 6a3f5d0b1f35)
  • PR diff matches the intended fix boundary: The PR changes only Discord token/account/status projection plus focused tests and carries tokenStatus without adding dependencies, workflow changes, or new runtime startup permissiveness. (extensions/discord/src/token.ts:24, f98e14b1d15a)
  • Prior changelog finding is addressed: The force-pushed diff now includes a single-line Unreleased Fixes entry for Discord unresolved SecretRef status snapshots. (CHANGELOG.md:17, f98e14b1d15a)

Likely related people:

  • steipete: Recent GitHub file history for the Discord token/status files shows multiple Discord helper and runtime-config commits, including the committer for the read-only accessor fix adjacent to this PR. (role: recent Discord maintainer; confidence: high; commits: 7e06455e64bb, 5d9941c36d4c, e4ca4c7fbf15; files: extensions/discord/src/token.ts, extensions/discord/src/shared.ts)
  • joshavant: Introduced the inspect/strict SecretRef resolver behavior and earlier read-only SecretRef status degradation contract that this PR reuses. (role: SecretRef/status contract owner; confidence: high; commits: 1769fb2aa1d6, 0e4245063f20; files: src/config/types.secrets.ts, src/channels/account-snapshot-fields.ts, extensions/discord/src/account-inspect.ts)
  • vincentkoc: Local current-main blame and recent API history connect this person to channel health/status snapshot work adjacent to the configured_unavailable surface. (role: adjacent channel status maintainer; confidence: medium; commits: 8ec589c9becd, be6263da4f51; files: extensions/discord/src/token.ts, extensions/discord/src/shared.ts, src/channels/account-snapshot-fields.ts)

Remaining risk / open question:

  • The PR is still draft and the exact head has not shown broad changed-gate or targeted Discord test results in public checks.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 6a3f5d0b1f35.

@rendrag-git rendrag-git force-pushed the codex/discord-secretref-configured-unavailable branch from 761a61f to f98e14b Compare May 3, 2026 03:59
@joshavant
Copy link
Copy Markdown
Contributor

Thanks @rendrag-git for the patch. The merged fix in #76449 covers the Discord SecretRef configured/startup state through the generic external channel secret-contract path and keeps unresolved configured SecretRefs reported as configured but unavailable. Closing this PR as superseded by the merged fix.

@joshavant joshavant closed this May 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: discord Channel integration: discord size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants