openclaw - ✅(Solved) Fix [Bug]: openclaw status shows empty Channels table while openclaw channels status shows channels correctly [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#73525Fetched 2026-04-29 06:18:47
View on GitHub
Comments
1
Participants
2
Timeline
3
Reactions
0
Author
Timeline (top)
cross-referenced ×2commented ×1

openclaw status shows an empty Channels table (only headers, no data rows) while openclaw channels status correctly shows all configured channels. The channels are actually running properly - this is a display bug in the status command.

Root Cause

openclaw status shows an empty Channels table (only headers, no data rows) while openclaw channels status correctly shows all configured channels. The channels are actually running properly - this is a display bug in the status command.

Fix Action

Fixed

PR fix notes

PR #73662: CLI/status: synthesize Channels rows from gateway snapshot when read-only discovery returns none

Description (problem / solution / changelog)

Summary

  • Problem: openclaw status renders a header-only Channels table while openclaw channels status correctly shows configured Telegram accounts as enabled, configured, running, and connected. Regression in 2026.4.24+. collectStatusScanOverview() queries the gateway for channels.status but only consumes that payload as an issue overlay; the visible Channels table is built exclusively from read-only plugin discovery (buildChannelsTable), which can return empty rows when running config relies on credentials/state the read-only path does not surface.
  • Why it matters: openclaw status is the canonical operator probe; an empty Channels table when channels are obviously running is a confusing regression that contradicts the working openclaw channels status command on the same node.
  • What changed: added mergeChannelsTableWithGatewayStatus({ channels, channelsStatus }) in src/commands/status-all/channels.ts. For each channel id present in channelsStatus.channelAccounts but missing from channels.rows, it synthesizes a generic ChannelRow derived from the live gateway account snapshot. Wired into collectStatusScanOverview after buildChannelsTable and exposed through statusScanRuntime.
  • What did NOT change (scope boundary): buildChannelsTable itself stays pure read-only discovery; formatGatewayChannelsStatusLines (the openclaw channels status formatter) is untouched; unreachable-gateway behavior still falls back to the read-only path.

Scope decision worth flagging

This augments missing rows; it does not replace existing read-only rows when the gateway snapshot also has data for them. clawsweeper's wording on the issue suggested "build the visible rows from the gateway snapshot" outright; I chose augment-mode because the read-only path provides richer per-channel detail via plugin.status?.buildChannelSummary and collectStatusIssues (link state, auth age, missing files, etc.) that would be lost under replace-mode. Happy to swap to replace-mode if maintainers prefer the broader interpretation; a single-line behavior change in mergeChannelsTableWithGatewayStatus would do it.

Synthesis logic

For each channel id missing from channels.rows:

  • Filter accounts to enabled === true (with asNullableRecord narrowing for safety on malformed entries); skip the channel if zero remain.
  • State precedence: lastError -> warn (highest); else all-running-and-connected-and-configured -> ok; else any transport problem (running false / disconnected) -> warn; else (running+connected but unconfigured) -> setup. State precedence is documented inline.
  • Detail: lastError message preferred; otherwise terse "running" / "running · accounts N" / "not running · not configured" style summary.
  • Label: channelsStatus.channelLabels[channelId] if a non-empty string, else channel id verbatim.

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 #73525
  • Related: N/A
  • This PR fixes a bug or regression

Root Cause

  • Root cause: collectStatusScanOverview() queries channels.status from the gateway and uses the payload only for issue overlays via collectChannelStatusIssues. The visible Channels rows come exclusively from buildChannelsTable(cfg, { sourceConfig }), which uses read-only plugin discovery (listReadOnlyChannelPluginsForConfig). When that discovery path returns no plugins for a channel that the gateway is actively running, the rendered Channels table is empty even though the gateway snapshot lists the running accounts.
  • Missing detection / guardrail: there was no test asserting parity (or augmentation) between openclaw status Channels rows and the live gateway snapshot for an actively running channel.
  • Contributing context: the regression appears in 2026.4.24+. The adjacent #72993 changelog entry kept default status fast while showing configured Telegram channels through setup metadata, but it did not address the live-gateway-vs-config table source mismatch reported in #73525.

Regression Test Plan

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/commands/status-all/channels.merge-gateway.test.ts (new): 11 cases — single-account synthesis, multi-account aggregation, isolated lastError precedence (with everything else healthy, proving error wins over ok), warn for transport problems, preservation of existing rows by reference, null/empty gateway payloads, all-disabled accounts, mixed enabled/disabled, the setup state branch, channelLabels fallback to channel id verbatim, malformed payload entries (null/primitives) skipped gracefully.
    • src/commands/status.scan-overview.test.ts: new case "merges live channels.status accounts into the visible Channels table (issue #73525)" asserts the merge helper is invoked with the expected args and the synthesized rows flow into result.channels.rows.
  • Scenario the test should lock in: any future change that drops the gateway-payload-to-rows merge inside the status path will fail both layers of tests.
  • Why this is the smallest reliable guardrail: the unit tests pin the synthesis matrix; the integration test pins the call seam.

User-visible / Behavior Changes

openclaw status now shows a populated Channels table whenever the gateway is reachable and reports running channel accounts, even when the read-only plugin discovery path produces no rows. No new flag, config, or output-shape changes. Existing rows from the read-only discovery path (when they are present) are preserved untouched.

Diagram

Before (per `openclaw status`, gateway reachable):
  channels.status payload  --(issue overlay only)-->  channelIssues
  buildChannelsTable        --(rows)-->                Channels table  (header-only when discovery is empty)

After (per `openclaw status`, gateway reachable):
  channels.status payload  --(issue overlay)-->        channelIssues
                            --(synthesis)-->           merge(buildChannelsTable rows, channelAccounts)
                                                            \-> Channels table  (populated from gateway snapshot when discovery is empty)

Unreachable gateway: unchanged. Falls back to read-only buildChannelsTable rows only.

Security Impact

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No (consumes the existing channels.status payload)
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: Linux 6.8.0 (CT 112 prbuild sandbox: Ubuntu 24.04, 4 cores, 6 GB RAM)
  • Runtime/container: Node 22, OpenClaw 2026.4.27
  • Model/provider: N/A (CLI-only path)
  • Integration/channel: Telegram (per #73525 reporter)
  • Relevant config: minimal channels.telegram.accounts.default.enabled: true (matching the reporter's reproduction)

Steps

  1. pnpm test src/commands/status-all/channels.merge-gateway.test.ts -> 11 tests pass.
  2. pnpm test src/commands/status.scan-overview.test.ts -> 3 tests pass (existing 2 + new merge regression case).
  3. pnpm test src/commands/status.scan.test.ts src/commands/status.scan.fast-json.test.ts src/commands/status.scan-execute.test.ts src/commands/status.scan-result.test.ts src/commands/status.command-report-data.test.ts src/commands/status.command-report.test.ts src/commands/status-all/channels-table.test.ts src/commands/channels/capabilities.test.ts src/infra/channels-status-issues.test.ts src/commands/status.summary.test.ts -> 34 tests pass; no regressions in any helper consumer.

Expected

When channelsStatus.channelAccounts.telegram reports an enabled: true, configured: true, running: true, connected: true account and buildChannelsTable returns no rows for telegram, the merged channels.rows contains a single row with id: "telegram", state: "ok", detail: "running".

Actual

Matches expected. RED phase confirmed: against unmodified source the new tests fail with mergeChannelsTableWithGatewayStatus is not a function.

Evidence

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

Human Verification

  • Verified scenarios:
    • TDD red->green on the new helper test file (11/11 fail without the helper, 11/11 pass with).
    • Existing openclaw channels status formatter (formatGatewayChannelsStatusLines) untouched; its tests still pass.
    • Existing read-only buildChannelsTable consumers (status.scan-overview, status.scan, status.scan-result, status.command-report, status.command-report-data, status.summary) all still pass.
    • pnpm tsgo (core) and pnpm check:test-types (core+extensions test types) both clean.
    • pnpm exec oxlint --type-aware and pnpm exec oxfmt --check clean on touched files and CHANGELOG.
    • Malformed gateway payload entries (null, primitives, non-record array members) skipped via asNullableRecord narrowing instead of crashing.
  • Edge cases checked:
    • Existing rows preserved by reference equality (asserted in tests).
    • Empty/null channelsStatus -> returns the original table unchanged.
    • All-disabled accounts -> no synthesized row.
    • lastError precedence isolated from connected: false (proved error wins over ok).
  • What you did not verify: live openclaw status end-to-end on a real gateway with a Telegram account, against a binary build. The regression tests pin the call-seam contract; the behavior claim is grounded in the synthesis matrix the unit tests cover.

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.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No

Risks and Mitigations

  • Risk: synthesized rows could mask a misconfigured plugin that the read-only path was correctly omitting from the table.
    • Mitigation: synthesis runs only when channelsStatus is non-null (gateway reachable). It does not replace existing rows; it only fills gaps. Operators get a Channels table that matches openclaw channels status, which is what they expect when those two commands disagree.
  • Risk: malformed gateway payload could crash the helper.
    • Mitigation: each account entry is narrowed via asNullableRecord before any property access; non-record entries are filtered out. Covered by the "malformed payload entries" unit test.

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/commands/status-all/channels.merge-gateway.test.ts (added, +254/-0)
  • src/commands/status-all/channels.ts (modified, +136/-1)
  • src/commands/status.scan-overview.test.ts (modified, +41/-0)
  • src/commands/status.scan-overview.ts (modified, +9/-3)
  • src/commands/status.scan.runtime.ts (modified, +2/-1)

Code Example

Channels
┌──────────┬─────────┬────────┬────────────────────────────────────────────────────────────────────────────────────────┐
ChannelEnabledStateDetail├──────────┼─────────┼────────┼────────────────────────────────────────────────────────────────────────────────────────┤
└──────────┴─────────┴────────┴────────────────────────────────────────────────────────────────────────────────────────┘

---

- Telegram 8679192687: enabled, configured, running, connected, mode:polling, token:config
- Telegram default: enabled, configured, running, connected, in:just now, mode:polling, token:config

---

{
  "channels": {
    "telegram": {
      "enabled": true,
      "accounts": {
        "default": {
          "enabled": true
        }
      }
    }
  }
}
RAW_BUFFERClick to expand / collapse

Bug type

Regression

Summary

openclaw status shows an empty Channels table (only headers, no data rows) while openclaw channels status correctly shows all configured channels. The channels are actually running properly - this is a display bug in the status command.

Steps to reproduce

  1. Run openclaw status
  2. Observe the Channels section - the table has headers but no data rows
  3. Run openclaw channels status
  4. Observe that channels are correctly displayed

Expected behavior

The Channels section in openclaw status should show all configured channels, similar to openclaw channels status.

Actual behavior

The Channels table in openclaw status is empty:

Channels
┌──────────┬─────────┬────────┬────────────────────────────────────────────────────────────────────────────────────────┐
│ Channel  │ Enabled │ State  │ Detail                                                                                 │
├──────────┼─────────┼────────┼────────────────────────────────────────────────────────────────────────────────────────┤
└──────────┴─────────┴────────┴────────────────────────────────────────────────────────────────────────────────────────┘

Meanwhile openclaw channels status shows:

- Telegram 8679192687: enabled, configured, running, connected, mode:polling, token:config
- Telegram default: enabled, configured, running, connected, in:just now, mode:polling, token:config

Configuration

{
  "channels": {
    "telegram": {
      "enabled": true,
      "accounts": {
        "default": {
          "enabled": true
        }
      }
    }
  }
}

Version

OpenClaw 2026.4.26

Additional context

  • This appears to be a new regression - not fixed in 2026.4.27 changelog
  • The channels are actually running correctly (visible in openclaw channels status)
  • Only the display in openclaw status is broken

extent analysis

TL;DR

The issue can be mitigated by using openclaw channels status instead of openclaw status to view channel information.

Guidance

  • Verify that the channels are correctly configured in the JSON configuration file, ensuring that the "enabled" field is set to true for each channel.
  • Compare the output of openclaw channels status with the expected output to confirm that channels are running correctly.
  • Check the OpenClaw version and look for any updates or patches that may address the regression.
  • Consider reporting the issue to the OpenClaw developers or community, as it appears to be a new regression that is not fixed in the latest version (2026.4.27).

Example

No code snippet is provided as it is not necessary for this issue.

Notes

The issue seems to be specific to the openclaw status command and does not affect the actual functionality of the channels. The workaround is to use openclaw channels status to view channel information.

Recommendation

Apply workaround: use openclaw channels status to view channel information, as the openclaw status command is currently not displaying channel data correctly.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

The Channels section in openclaw status should show all configured channels, similar to openclaw channels status.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING