diff --git a/CHANGELOG.md b/CHANGELOG.md index 263cd9b73d5..598ce514916 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,7 @@ Docs: https://docs.openclaw.ai - Config/$schema: preserve root-authored `$schema` during partial config rewrites without injecting include-only schema URLs into the root config. (#47322) Thanks @EfeDurmaz16. - Agents/CLI delivery: run the same reply-media path normalizer the auto-reply flow uses before shipping `openclaw agent --deliver` payloads, so relative `MEDIA:./out/photo.png` tokens resolve against the agent workspace instead of being rejected downstream with `LocalMediaAccessError: Local media path is not under an allowed directory`. Thanks @frankekn. - Agents/Google: strip `thinkingBudget=0` for the thinking-required `gemini-2.5-pro` model in embedded-runner and native Google payloads, so requests no longer fail with `Budget 0 is invalid. This model only works in thinking mode.` and the API uses its default thinking behavior instead. (#68607) Thanks @josmithiii. +- Slack/threads: log failed thread starter and history fetches at verbose level while preserving best-effort fallback behavior, so missing Slack thread context is diagnosable without interrupting inbound handling. (#68594) Thanks @martingarramon. ## 2026.4.15 diff --git a/extensions/slack/src/monitor/media.test.ts b/extensions/slack/src/monitor/media.test.ts index 45c154a22cc..f543ef2375b 100644 --- a/extensions/slack/src/monitor/media.test.ts +++ b/extensions/slack/src/monitor/media.test.ts @@ -895,7 +895,13 @@ describe("resolveSlackThreadStarter", () => { client, }); - expect(result).toEqual({ text: "hello thread", userId: "U1", botId: undefined, ts: "1.000", files: undefined }); + expect(result).toEqual({ + text: "hello thread", + userId: "U1", + botId: undefined, + ts: "1.000", + files: undefined, + }); expect(vi.mocked(logVerbose)).not.toHaveBeenCalled(); }); diff --git a/extensions/slack/src/monitor/media.ts b/extensions/slack/src/monitor/media.ts index d9a59996cac..2743f8e48c2 100644 --- a/extensions/slack/src/monitor/media.ts +++ b/extensions/slack/src/monitor/media.ts @@ -1,4 +1,5 @@ import type { WebClient as SlackWebClient } from "@slack/web-api"; +import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; import { normalizeHostname } from "openclaw/plugin-sdk/host-runtime"; import { fetchWithRuntimeDispatcher } from "openclaw/plugin-sdk/infra-runtime"; import type { FetchLike } from "openclaw/plugin-sdk/media-runtime"; @@ -450,7 +451,7 @@ export async function resolveSlackThreadStarter(params: { return starter; } catch (err) { logVerbose( - `slack thread starter fetch failed channel=${params.channelId} ts=${params.threadTs}: ${err instanceof Error ? err.message : String(err)}`, + `slack thread starter fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`, ); return null; } @@ -545,7 +546,7 @@ export async function resolveSlackThreadHistory(params: { })); } catch (err) { logVerbose( - `slack thread history fetch failed channel=${params.channelId} ts=${params.threadTs}: ${err instanceof Error ? err.message : String(err)}`, + `slack thread history fetch failed channel=${params.channelId} ts=${params.threadTs}: ${formatErrorMessage(err)}`, ); return []; } diff --git a/scripts/check-no-raw-channel-fetch.mjs b/scripts/check-no-raw-channel-fetch.mjs index 01d486d539a..3ad0fbb699d 100644 --- a/scripts/check-no-raw-channel-fetch.mjs +++ b/scripts/check-no-raw-channel-fetch.mjs @@ -60,9 +60,9 @@ const allowedRawFetchCallsites = new Set([ bundledPluginCallsite("qqbot", "src/tools/channel.ts", 180), bundledPluginCallsite("qqbot", "src/utils/audio-convert.ts", 377), bundledPluginCallsite("signal", "src/install-signal-cli.ts", 224), - bundledPluginCallsite("slack", "src/monitor/media.ts", 97), - bundledPluginCallsite("slack", "src/monitor/media.ts", 116), - bundledPluginCallsite("slack", "src/monitor/media.ts", 121), + bundledPluginCallsite("slack", "src/monitor/media.ts", 98), + bundledPluginCallsite("slack", "src/monitor/media.ts", 117), + bundledPluginCallsite("slack", "src/monitor/media.ts", 122), bundledPluginCallsite("tlon", "src/tlon-api.ts", 185), bundledPluginCallsite("tlon", "src/tlon-api.ts", 235), bundledPluginCallsite("tlon", "src/tlon-api.ts", 289),