openclaw - ✅(Solved) Fix RFE: expose Slack channel log level via openclaw.json (e.g., channels.slack.logLevel) so operators can suppress designed-and-benign socket-mode noise [1 pull requests, 1 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#71531Fetched 2026-04-26 05:11:49
View on GitHub
Comments
0
Participants
1
Timeline
6
Reactions
0
Author
Participants
Timeline (top)
referenced ×5cross-referenced ×1

Error Message

[WARN] socket-mode:SlackWebSocket:NN A pong wasn't received from the server before the timeout of 5000ms! warn call is unconditional: this.logger.warn(A pong wasn't received from the server before the timeout of ${this.options.clientPingTimeoutMS}ms!); The library auto-reconnects cleanly. The WARN is noise, not a failure signal — But the pong WARN above is NOT gated by that flag — it fires unconditionally constructor, which would set the bolt logger to ERROR and suppress library No logger/logLevel is passed → bolt defaults to LogLevel.INFO → WARN const slackLogLevel = config.channels?.slack?.logLevel; // "DEBUG" | "INFO" | "WARN" | "ERROR" Default could remain WARN (current effective behavior); operators wanting quiet ops logs would set "logLevel": "ERROR". A single channels.slack.logLevel covers the pong WARN, any other library

Fix Action

Fix / Workaround

Workaround in use

PR fix notes

PR #71550: feat(slack): expose channels.slack.logLevel so operators can silence socket-mode pong-timeout noise (#71531)

Description (problem / solution / changelog)

Closes #71531.

Bug

The bundled @slack/socket-mode 2.0.6 emits an unconditional WARN every ~30s when the periodic pong is late:

A pong wasn't received from the server before the timeout of 5000ms!

The library auto-reconnects cleanly, so the WARN is noise, not a failure signal — but it floods gateway.err.log and operators end up filtering it externally to recover signal-to-noise. The existing pingPongLoggingEnabled flag is already the default false in 2.0.6 but does NOT gate the pong-timeout WARN — it fires unconditionally in SlackWebSocket.js.

The only effective knob is bolt's App({ logLevel }) option, which gates ALL sub-library output. openclaw was not passing it, so bolt defaulted to INFO.

Fix

Add an optional channels.slack.logLevel knob (DEBUG | INFO | WARN | ERROR) and forward it to bolt's App constructor when set. When omitted, behavior is unchanged (bolt's INFO default).

channels:
  slack:
    logLevel: ERROR   # silences socket-mode pong-timeout WARNs

Diff

  • src/config/zod-schema.providers-core.ts — add logLevel to SlackConfigSchema
  • extensions/slack/src/monitor/provider-support.ts — accept + forward logLevel in createSlackBoltApp
  • extensions/slack/src/monitor/provider.ts — thread slackCfg.logLevel through
  • extensions/slack/src/monitor/provider.interop.test.ts — 2 new tests:
    • forwards logLevel to bolt's App when provided
    • omits logLevel when not set so bolt's INFO default is preserved

48 LOC across 4 files. Lint clean (pnpm oxlint — 0 warnings, 0 errors).

Out of scope

  • Per-account override (channels.slack.accounts.<id>.logLevel) — can be added later if needed; the channel-level knob covers the reported use case.
  • Per-sub-library filtering — bolt doesn't expose this granularity directly.
  • Custom logger injection — same.

🤖 generated with assistance from Claude Code Co-authored-by: HCL [email protected]

Changed files

  • extensions/slack/src/monitor/provider-support.ts (modified, +14/-0)
  • extensions/slack/src/monitor/provider.interop.test.ts (modified, +35/-0)
  • extensions/slack/src/monitor/provider.ts (modified, +5/-0)
  • src/config/zod-schema.providers-core.ts (modified, +6/-0)

Code Example

[WARN] socket-mode:SlackWebSocket:NN A pong wasn't received from the server before the timeout of 5000ms!

---

if (isInvalid) {
    this.logger.warn(`A pong wasn't received from the server before the timeout of ${this.options.clientPingTimeoutMS}ms!`);
    this.disconnect();
}

---

const app = new App(slackMode === "socket" ? {
    token: botToken,
    appToken,
    socketMode: true,
    clientOptions
} : {
    token: botToken,
    receiver: receiver ?? void 0,
    clientOptions
});

---

const slackLogLevel = config.channels?.slack?.logLevel; // "DEBUG" | "INFO" | "WARN" | "ERROR"
const app = new App({
    token: botToken,
    appToken,
    socketMode: true,
    clientOptions,
    ...(slackLogLevel ? { logLevel: LogLevel[slackLogLevel] } : {}),
});

---

\[whatsapp\] Web connection closed \(status (499|428|503|408)
\[whatsapp\] No messages received in 30m - restarting connection
socket-mode:SlackWebSocket:[0-9]+ A pong wasn't received from the server before the timeout
\[bonjour\] watchdog detected non-announced service
RAW_BUFFERClick to expand / collapse

Observed

Every ~30s, gateway.err.log emits:

[WARN] socket-mode:SlackWebSocket:NN A pong wasn't received from the server before the timeout of 5000ms!

Source: bundled @slack/socket-mode 2.0.6 → SlackWebSocket.js, where the warn call is unconditional:

if (isInvalid) {
    this.logger.warn(`A pong wasn't received from the server before the timeout of ${this.options.clientPingTimeoutMS}ms!`);
    this.disconnect();
}

The library auto-reconnects cleanly. The WARN is noise, not a failure signal — operators eventually start filtering it at the log layer to recover usable signal-to-noise on gateway.err.log.

Existing knob doesn't help

pingPongLoggingEnabled: false is the default in @slack/socket-mode 2.0.6. But the pong WARN above is NOT gated by that flag — it fires unconditionally in SlackWebSocket.js. Setting the flag to false changes nothing.

The only effective knob is logLevel (or a custom logger) on bolt's App constructor, which would set the bolt logger to ERROR and suppress library WARNs. openclaw currently does not pass either.

Where openclaw constructs the bolt App today

In the bundled gateway (dist/provider-…js):

const app = new App(slackMode === "socket" ? {
    token: botToken,
    appToken,
    socketMode: true,
    clientOptions
} : {
    token: botToken,
    receiver: receiver ?? void 0,
    clientOptions
});

No logger/logLevel is passed → bolt defaults to LogLevel.INFO → WARN messages from sub-libraries (socket-mode included) reach stderr.

Proposed

openclaw.json should accept a per-channel log-level knob — e.g. channels.slack.logLevel (or channels.slack.bolt.logLevel for clarity that it's plumbing through to bolt).

Wired at the upstream call site:

const slackLogLevel = config.channels?.slack?.logLevel; // "DEBUG" | "INFO" | "WARN" | "ERROR"
const app = new App({
    token: botToken,
    appToken,
    socketMode: true,
    clientOptions,
    ...(slackLogLevel ? { logLevel: LogLevel[slackLogLevel] } : {}),
});

Default could remain WARN (current effective behavior); operators wanting quiet ops logs would set "logLevel": "ERROR".

Versions

  • openclaw: 2026.4.5
  • @slack/bolt: 4.6.0
  • @slack/socket-mode: 2.0.6

Workaround in use

Operator-side wrapper-script log-filter daemon producing a parallel gateway.err.clean.log that strips the four designed-and-benign reconnect patterns. Works, but adds infrastructure that should not be necessary if the upstream config knob existed.

Filter pattern in use (for reference):

\[whatsapp\] Web connection closed \(status (499|428|503|408)
\[whatsapp\] No messages received in 30m - restarting connection
socket-mode:SlackWebSocket:[0-9]+ A pong wasn't received from the server before the timeout
\[bonjour\] watchdog detected non-announced service

Why filing as a single config knob (not 4 separate flags)

A single channels.slack.logLevel covers the pong WARN, any other library WARNs, and is the standard bolt-shaped escape hatch. Separate booleans for specific message classes would balloon the config surface area.

extent analysis

TL;DR

To fix the issue, add a logLevel configuration option to the App constructor in the openclaw gateway to suppress the unwanted WARN messages from the @slack/socket-mode library.

Guidance

  • The pingPongLoggingEnabled flag does not affect the WARN message, so it's not a viable solution.
  • Setting the logLevel to ERROR on the App constructor would suppress the WARN messages, but this requires passing a custom logger or logLevel option when creating the App instance.
  • The proposed solution involves adding a channels.slack.logLevel configuration option to openclaw.json and passing it to the App constructor.
  • To verify the fix, check the gateway.err.log file for the absence of the WARN messages after applying the configuration change.

Example

const slackLogLevel = config.channels?.slack?.logLevel; 
const app = new App({
    token: botToken,
    appToken,
    socketMode: true,
    clientOptions,
    ...(slackLogLevel ? { logLevel: LogLevel[slackLogLevel] } : {}),
});

Notes

The current workaround using a log-filter daemon can be removed once the configuration option is implemented.

Recommendation

Apply the proposed workaround by adding the channels.slack.logLevel configuration option to openclaw.json and passing it to the App constructor, as it provides a standard and flexible way to control logging levels.

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix RFE: expose Slack channel log level via openclaw.json (e.g., channels.slack.logLevel) so operators can suppress designed-and-benign socket-mode noise [1 pull requests, 1 participants]