Skip to content

Channels: move single-account config into accounts.default#27334

Merged
gumadeiras merged 5 commits intomainfrom
codex/move-single-account-values-to-default
Feb 26, 2026
Merged

Channels: move single-account config into accounts.default#27334
gumadeiras merged 5 commits intomainfrom
codex/move-single-account-values-to-default

Conversation

@gumadeiras
Copy link
Member

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: openclaw channels add for a non-default account could leave single-account channel values at top-level while adding accounts.<new>, causing split/duplicated account state and breaking the original account path in real configs.
  • Why it matters: users upgrading from single-account to multi-account could lose working behavior for the original account and end up with confusing mixed config shape.
  • What changed: added shared migration logic to move account-scoped top-level single-account values into channels.<channel>.accounts.default before writing non-default accounts; wired this into non-interactive channels add, onboarding scoped account patching, and doctor repair migration.
  • What did NOT change (scope boundary): channel-only bindings are not auto-rewritten to explicit accountId=default; routing semantics remain the same (channel-only binding still targets default account).

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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 #

User-visible / Behavior Changes

  • Adding a non-default account now moves account-scoped top-level single-account channel values into accounts.default (instead of duplicating/copying).
  • Original default-account behavior is preserved after migration.
  • openclaw doctor --fix repairs already-mixed channel account shapes with the same move behavior.
  • Docs updated for channels/CLI/config-reference/doctor.

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Node 22+ / pnpm workspace
  • Model/provider: N/A
  • Integration/channel (if any): Telegram (regression tests), generic plugin/onboarding/doctor paths
  • Relevant config (redacted): single-account channel root values + add non-default account

Steps

  1. Start with channel config that has single-account values at channels.<channel>.* and no accounts object.
  2. Run openclaw channels add --channel telegram --account alerts --token <token> (non-interactive path), or use onboarding scoped account path.
  3. Inspect resulting config.
  4. Run openclaw doctor --fix on mixed-shape config (accounts exists, default missing, top-level account values still present).

Expected

  • Top-level account-scoped single-account values are moved into channels.<channel>.accounts.default.
  • New account is written under channels.<channel>.accounts.<new>.
  • Channel-only bindings keep matching default account.

Actual

  • Matches expected (verified by targeted tests below).

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:
    • non-interactive channels add moves single-account channel values into accounts.default when adding non-default account.
    • onboarding scoped account patch path performs the same migration.
    • doctor migration repairs mixed shape (accounts named entries + missing default + top-level account-scoped values).
  • Edge cases checked:
    • migration only moves account-scoped keys, preserving global channel-level values at root.
    • Telegram-specific streaming move path covered by tests.
  • What you did not verify:
    • full cross-channel manual runtime smoke across all integrations; relied on shared-path + targeted regression coverage.

Compatibility / Migration

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

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly:
    • Revert this PR commit.
  • Files/config to restore:
    • Restore src/channels/plugins/setup-helpers.ts, src/commands/channels/add.ts, src/channels/plugins/onboarding/helpers.ts, src/commands/doctor-legacy-config.ts and rerun tests.
  • Known bad symptoms reviewers should watch for:
    • unexpected movement of channel-global keys into accounts.default.
    • missing default-account routing after non-default account add.

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk:
    • moving an unintended key from channel root to accounts.default could change provider behavior.
    • Mitigation:
      • migration uses explicit allowlist of account-scoped keys (plus channel-specific exceptions), with regression tests covering Telegram account + doctor paths.

Copilot AI review requested due to automatic review settings February 26, 2026 08:21
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation gateway Gateway runtime commands Command implementations size: M maintainer Maintainer-authored PR labels Feb 26, 2026
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Moves account-scoped channel config values into accounts.default when adding non-default accounts, preserving original single-account behavior while transitioning to multi-account structure.

  • Implements shared migration helper moveSingleAccountChannelSectionToDefaultAccount with explicit allowlist of account-scoped keys (token, botToken, dmPolicy, streaming, etc.)
  • Integrates migration into three paths: non-interactive channels add, onboarding scoped account patching, and doctor --fix repair for mixed configs
  • Migration runs only when needed: skips if accounts already exist (channels add path) or if default account present (doctor path)
  • Preserves channel-level settings like enabled at root; only moves account-scoped values
  • Comprehensive test coverage verifies Telegram account migration and doctor repair scenarios
  • Documentation clearly explains behavior and routing semantics (channel-only bindings continue matching default account)

Confidence Score: 5/5

  • This PR is safe to merge with high confidence
  • The implementation is well-structured with defensive programming (early returns, type checks, allowlist-based key filtering), comprehensive test coverage across all integration points (channels add, onboarding, doctor), and clear documentation. The migration logic correctly handles edge cases and runs only when appropriate. No bugs or security issues found.
  • No files require special attention

Last reviewed commit: 162a752

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds migration logic to move single-account channel configuration values into channels.<channel>.accounts.default when adding non-default accounts, preventing config duplication and preserving original account behavior during the single→multi-account upgrade path.

Changes:

  • Added shared migration function moveSingleAccountChannelSectionToDefaultAccount with explicit allowlist of account-scoped keys (common + channel-specific like Telegram's streaming)
  • Wired migration into non-interactive channels add command, onboarding scoped account patching, and openclaw doctor --fix repair flow
  • Updated CLI, channels, configuration, and doctor documentation with migration behavior and repair guidance

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/channels/plugins/setup-helpers.ts Core migration logic: shouldMoveSingleAccountChannelKey allowlist checker and moveSingleAccountChannelSectionToDefaultAccount function to move account-scoped top-level values into accounts.default
src/commands/channels/add.ts Invoke migration before applying new account config when adding non-default accounts
src/channels/plugins/onboarding/helpers.ts Invoke migration in patchConfigForScopedAccount when patching non-default accounts via onboarding
src/commands/doctor-legacy-config.ts Add seedMissingDefaultAccountsFromSingleAccountBase repair migration for already-mixed configs (accounts exist, default missing, top-level values present)
src/commands/channels.adds-non-default-telegram-account.test.ts Test coverage for channels add migration path with Telegram account and streaming field
src/channels/plugins/onboarding/helpers.test.ts Test coverage for onboarding patch migration path
src/commands/doctor-legacy-config.migrations.test.ts Test coverage for doctor repair migration; updated streaming migration test expectations to use .toContain for multiple changes
docs/gateway/doctor.md Document new doctor migration for missing default accounts
docs/gateway/configuration-reference.md Document automatic migration behavior when adding non-default accounts
docs/cli/index.md Document channels add migration behavior and binding semantics
docs/cli/channels.md Detailed documentation of migration flow, routing behavior, and doctor repair guidance
CHANGELOG.md Changelog entry for the fix

@gumadeiras gumadeiras self-assigned this Feb 26, 2026
@gumadeiras gumadeiras force-pushed the codex/move-single-account-values-to-default branch from 4d12bf3 to 83f23c1 Compare February 26, 2026 08:40
@gumadeiras gumadeiras force-pushed the codex/move-single-account-values-to-default branch from e794ac3 to d0f973a Compare February 26, 2026 08:55
@gumadeiras gumadeiras force-pushed the codex/move-single-account-values-to-default branch from ec54b9e to 50b5771 Compare February 26, 2026 09:05
@gumadeiras gumadeiras merged commit dfa0b5b into main Feb 26, 2026
6 of 7 checks passed
@gumadeiras gumadeiras deleted the codex/move-single-account-values-to-default branch February 26, 2026 09:06
@gumadeiras
Copy link
Member Author

Merged via squash.

Thanks @gumadeiras!

NOVA-Openclaw added a commit to NOVA-Openclaw/nova-openclaw that referenced this pull request Feb 26, 2026
Syncs 29 upstream commits including:
- Account-scoped bind and routing commands (openclaw#27195)
- Single-account config migration to accounts.default (openclaw#27334)
- Preserve agent-level apiKey/baseUrl during models.json merge (openclaw#27293)
- Plugin-owned interactive channel onboarding flows (openclaw#27191)
- Android notifications.list, invoke refactoring
- Daemon launchd restart hardening
- SSRF dispatcher fix, doctor improvements

Conflict resolution: 4 import-order conflicts in onboarding/channel
commands resolved by taking upstream (no custom code in those files).
FradSer pushed a commit to FradSer/openclaw that referenced this pull request Feb 26, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
steipete pushed a commit that referenced this pull request Feb 26, 2026
Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
execute008 pushed a commit to execute008/openclaw that referenced this pull request Feb 27, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
r4jiv007 pushed a commit to r4jiv007/openclaw that referenced this pull request Feb 28, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
vincentkoc pushed a commit to Sid-Qin/openclaw that referenced this pull request Feb 28, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
vincentkoc pushed a commit to rylena/rylen-openclaw that referenced this pull request Feb 28, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
steipete pushed a commit to Sid-Qin/openclaw that referenced this pull request Mar 2, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
robertchang-ga pushed a commit to robertchang-ga/openclaw that referenced this pull request Mar 2, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
dorgonman pushed a commit to kanohorizonia/openclaw that referenced this pull request Mar 3, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
thebenjaminlee pushed a commit to escape-velocity-ventures/openclaw that referenced this pull request Mar 7, 2026
…27334)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 50b5771
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

commands Command implementations docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants