Summary
Slack thread participation persistence appears to fail when the Slack plugin is loaded from a global/npm plugin install rather than as a bundled plugin. The visible symptom is repeated warnings:
Slack persistent thread participation state failed
After this happens, Slack group/thread follow-up messages without a fresh explicit @mention are skipped, even if the bot has already replied in that thread. Explicitly tagging the bot again works.
Expected behavior
When the bot is explicitly mentioned in a Slack thread and delivers a reply, that thread should be recorded as bot-participated. Later messages in the same thread should be eligible for implicit activation according to the existing thread participation logic, without requiring a fresh @mention each time.
Actual behavior
The bot replies when explicitly mentioned, but later unmentioned thread replies are skipped as no-mention. The persistent participation state is not written, and logs repeatedly show:
Slack persistent thread participation state failed
The warning currently does not include the underlying exception in the rendered logs, because the logger wrapper appears to drop the second object argument passed here:
.warn("Slack persistent thread participation state failed", { error: String(error) })
Investigation notes
Version observed:
openclaw: 2026.5.12
@openclaw/slack: 2026.5.12
Installed plugin index showed Slack loaded as a global plugin, for example:
{
"pluginId": "slack",
"origin": "global",
"manifestPath": ".../.openclaw/npm/node_modules/@openclaw/slack/openclaw.plugin.json"
}
The Slack participation code opens persistent state with:
runtime.state.openKeyedStore({
namespace: "slack.thread-participation",
maxEntries: 1000,
defaultTtlMs: 1440 * 60 * 1000
})
The plugin loader proxy only permits keyed state for bundled plugins:
if ((pluginRuntimeRecordById.get(pluginId) ?? registry.plugins.find((entry) => entry.id === pluginId))?.origin !== "bundled") {
throw new Error("openKeyedStore is only available for bundled plugins in this release.");
}
That makes the Slack persistence code fail when @openclaw/slack is loaded as origin: "global".
I also verified the local plugin-state SQLite database itself was healthy and writable. Older slack.thread-participation rows existed from before the global Slack plugin install, but no new participation rows were created after Slack was loaded globally. This points to the plugin-origin/runtime permission path rather than DB corruption or Slack thread_ts parsing.
Impact
This breaks the intended behavior described in the code comment for Slack sent-thread cache:
Used to auto-respond in threads without requiring @mention after the first reply.
It affects Slack channels configured with requireMention: true, because participation cannot be persisted and later unmentioned thread replies fail the implicit mention check.
Possible fixes
A maintainer probably has better context, but likely options are:
- Ensure the Slack channel plugin is loaded as bundled when it needs bundled-only runtime state.
- Allow this specific official/global Slack plugin path to access
openKeyedStore if externalized bundled plugins are expected to work as global installs.
- Fall back to another state mechanism for Slack thread participation when
openKeyedStore is unavailable.
- Improve logging so
Slack persistent thread participation state failed includes the actual exception string in rendered logs.
Privacy note
This report intentionally omits workspace-specific Slack channel IDs, user IDs, tokens, file paths containing user names, and message contents. The paths above are abbreviated where appropriate.
Summary
Slack thread participation persistence appears to fail when the Slack plugin is loaded from a global/npm plugin install rather than as a bundled plugin. The visible symptom is repeated warnings:
After this happens, Slack group/thread follow-up messages without a fresh explicit @mention are skipped, even if the bot has already replied in that thread. Explicitly tagging the bot again works.
Expected behavior
When the bot is explicitly mentioned in a Slack thread and delivers a reply, that thread should be recorded as bot-participated. Later messages in the same thread should be eligible for implicit activation according to the existing thread participation logic, without requiring a fresh @mention each time.
Actual behavior
The bot replies when explicitly mentioned, but later unmentioned thread replies are skipped as no-mention. The persistent participation state is not written, and logs repeatedly show:
The warning currently does not include the underlying exception in the rendered logs, because the logger wrapper appears to drop the second object argument passed here:
Investigation notes
Version observed:
openclaw:2026.5.12@openclaw/slack:2026.5.12Installed plugin index showed Slack loaded as a global plugin, for example:
{ "pluginId": "slack", "origin": "global", "manifestPath": ".../.openclaw/npm/node_modules/@openclaw/slack/openclaw.plugin.json" }The Slack participation code opens persistent state with:
The plugin loader proxy only permits keyed state for bundled plugins:
That makes the Slack persistence code fail when
@openclaw/slackis loaded asorigin: "global".I also verified the local plugin-state SQLite database itself was healthy and writable. Older
slack.thread-participationrows existed from before the global Slack plugin install, but no new participation rows were created after Slack was loaded globally. This points to the plugin-origin/runtime permission path rather than DB corruption or Slackthread_tsparsing.Impact
This breaks the intended behavior described in the code comment for Slack sent-thread cache:
It affects Slack channels configured with
requireMention: true, because participation cannot be persisted and later unmentioned thread replies fail the implicit mention check.Possible fixes
A maintainer probably has better context, but likely options are:
openKeyedStoreif externalized bundled plugins are expected to work as global installs.openKeyedStoreis unavailable.Slack persistent thread participation state failedincludes the actual exception string in rendered logs.Privacy note
This report intentionally omits workspace-specific Slack channel IDs, user IDs, tokens, file paths containing user names, and message contents. The paths above are abbreviated where appropriate.