diff --git a/CHANGELOG.md b/CHANGELOG.md index e324a5460b3..18f8aa8301d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Agents/compaction safeguard pre-check: skip embedded compaction before entering the Pi SDK when a session has no real conversation messages, avoiding unnecessary LLM API calls on idle sessions. (#36451) thanks @Sid-Qin. +- Config/schema cache key stability: build merged schema cache keys with incremental hashing to avoid large single-string serialization and prevent `RangeError: Invalid string length` on high-cardinality plugin/channel metadata. (#36603) Thanks @powermaster888. - iMessage/cron completion announces: strip leaked inline reply tags (for example `[[reply_to:6100]]`) from user-visible completion text so announcement deliveries do not expose threading metadata. (#24600) Thanks @vincentkoc. - Sessions/daily reset transcript archival: archive prior transcript files during stale-session scheduled/daily resets by capturing the previous session entry before rollover, preventing orphaned transcript files on disk. (#35493) Thanks @byungsker. - Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands (for example `@Bot/model` and `@Bot /reset`) are recognized as gateway commands instead of being forwarded to the agent. (#35994) Thanks @liuxiaopai-ai. diff --git a/src/config/schema.ts b/src/config/schema.ts index 58d93215de1..406d61dce77 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -1,3 +1,4 @@ +import crypto from "node:crypto"; import { CHANNEL_IDS } from "../channels/registry.js"; import { VERSION } from "../version.js"; import type { ConfigUiHint, ConfigUiHints } from "./schema.hints.js"; @@ -322,7 +323,24 @@ function buildMergedSchemaCacheKey(params: { configUiHints: channel.configUiHints ?? null, })) .toSorted((a, b) => a.id.localeCompare(b.id)); - return JSON.stringify({ plugins, channels }); + // Build the hash incrementally so we never materialize one giant JSON string. + const hash = crypto.createHash("sha256"); + hash.update('{"plugins":['); + plugins.forEach((plugin, index) => { + if (index > 0) { + hash.update(","); + } + hash.update(JSON.stringify(plugin)); + }); + hash.update('],"channels":['); + channels.forEach((channel, index) => { + if (index > 0) { + hash.update(","); + } + hash.update(JSON.stringify(channel)); + }); + hash.update("]}"); + return hash.digest("hex"); } function setMergedSchemaCache(key: string, value: ConfigSchemaResponse): void {