Notas da versão
Changes
- Provider/Mistral: add support for the Mistral provider, including memory embeddings and voice support. (#23845) Thanks @vincentkoc.
- Update/Core: add an optional built-in auto-updater for package installs (
update.auto.*), default-off, with stable rollout delay+jitter and beta hourly cadence. - CLI/Update: add
openclaw update --dry-runto preview channel/tag/target/restart actions without mutating config, installing, syncing plugins, or restarting. - Config/UI: add tag-aware settings filtering and broaden config labels/help copy so fields are easier to discover and understand in the dashboard config screen.
- Channels/Synology Chat: add a native Synology Chat channel plugin with webhook ingress, direct-message routing, outbound send/media support, per-account config, and DM policy controls. (#23012)
- iOS/Talk: prefetch TTS segments and suppress expected speech-cancellation errors for smoother talk playback. (#22833) Thanks @ngutman.
- Memory/FTS: add Spanish and Portuguese stop-word filtering for query expansion in FTS-only search mode, improving conversational recall for both languages. Thanks @vincentkoc.
- Memory/FTS: add Japanese-aware query expansion tokenization and stop-word filtering (including mixed-script terms like ASCII + katakana) for FTS-only search mode. Thanks @vincentkoc.
- Memory/FTS: add Korean stop-word filtering and particle-aware keyword extraction (including mixed Korean/English stems) for query expansion in FTS-only search mode. (#18899) Thanks @ruypang.
- Memory/FTS: add Arabic stop-word filtering for query expansion in FTS-only search mode to reduce conversational filler in Arabic memory searches. Thanks @vincentkoc.
- Discord/Allowlist: canonicalize resolved Discord allowlist names to IDs and split resolution flow for clearer fail-closed behavior.
- Channels/Config: unify channel preview streaming config handling with a shared resolver and canonical migration path.
- Gateway/Auth: unify call/probe/status/auth credential-source precedence on shared resolver helpers, with table-driven parity coverage across gateway entrypoints.
- Gateway/Auth: refactor gateway credential resolution and websocket auth handshake paths to use shared typed auth contexts, including explicit
auth.deviceTokensupport in connect frames and tests. - Skills: remove bundled
food-orderskill from this repo; manage/install it from ClawHub instead. - Docs/Subagents: make thread-bound session guidance channel-first instead of Discord-specific, and list thread-supporting channels explicitly. (#23589) Thanks @osolmaz.
Fixes
- Security/CLI: redact sensitive values in
openclaw config getoutput before printing config paths, preventing credential leakage to terminal output/history. (#13683) Thanks @SleuthCo. - Install/Discord Voice: make
@discordjs/opusan optional dependency soopenclawinstall/update no longer hard-fails when native Opus builds fail, while keepingopusscriptas the runtime fallback decoder for Discord voice flows. (#23737, #23733, #23703) Thanks @jeadland, @Sheetaa, and @Breakyman. - Docker/Setup: precreate
$OPENCLAW_CONFIG_DIR/identityduringdocker-setup.shso CLI commands that need device identity (for exampledevices list) avoidEACCES ... /home/node/.openclaw/identityfailures on restrictive bind mounts. (#23948) Thanks @ackson-beep. - Exec/Background: stop applying the default exec timeout to background sessions (
background: trueor explicityieldMs) when no explicit timeout is set, so long-running background jobs are no longer terminated at the default timeout boundary. (#23303) - Slack/Threading: sessions: keep parent-session forking and thread-history context active beyond first turn by removing first-turn-only gates in session init, thread-history fetch, and reply prompt context injection. (#23843, #23090) Thanks @vincentkoc and @Taskle.
- Slack/Threading: respect
replyToModewhen Slack auto-populates top-levelthread_ts, and ignore inlinereplyToIddirective tags whenreplyToModeisoffso thread forcing stays disabled unless explicitly configured. (#23839, #23320, #23513) Thanks @vincentkoc and @dorukardahan. - Slack/Extension: forward
message readthreadIdtoreadMessagesand use delivery-contextthreadIdas outboundthread_tsfallback so extension replies/reads stay in the correct Slack thread. (#22216, #22485, #23836) Thanks @vincentkoc, @lan17 and @dorukardahan. - Slack/Upload: resolve bare user IDs (U-prefix) to DM channel IDs via
conversations.openbefore callingfiles.uploadV2, which rejects non-channel IDs.chat.postMessagetolerates user IDs directly, butfiles.uploadV2→completeUploadExternalvalidateschannel_idagainst^[CGDZ][A-Z0-9]{8,}$, causinginvalid_argumentswhen agents reply with media to DM conversations. - Webchat/Chat: apply assistant
finalpayload messages directly to chat state so sent turns render without waiting for a full history refresh cycle. (#14928) Thanks @BradGroux. - Webchat/Chat: for out-of-band final events (for example tool-call side runs), append provided final assistant payloads directly instead of forcing a transient history reset. (#11139) Thanks @AkshayNavle.
- Webchat/Performance: reload
chat.historyafter final events only when the final payload lacks a renderable assistant message, avoiding expensive full-history refreshes on normal turns. (#20588) Thanks @amzzzzzzz. - Webchat/Sessions: preserve external session routing metadata when internal
chat.sendturns run underwebchat, so explicit channel-keyed sessions (for example Telegram) no longer get rewritten towebchatand misroute follow-up delivery. (#23258) Thanks @binary64. - Webchat/Sessions: preserve existing session
labelacross/newand/resetrollovers so reset sessions remain discoverable in session history lists. (#23755) Thanks @ThunderStormer. - Gateway/Chat UI: strip inline reply/audio directive tags from non-streaming final webchat broadcasts (including
chat.inject) while preserving empty-string message content when tags are the entire reply. (#23298) Thanks @SidQin-cyber. - Chat/UI: strip inline reply/audio directive tags (
[[reply_to_current]],[[reply_to:<id>]],[[audio_as_voice]]) from displayed chat history, live chat event output, and session preview snippets so control tags no longer leak into user-visible surfaces. - Gateway/Chat UI: sanitize non-streaming final
chat.send/chat.injectpayload text with the same envelope/untrusted-context stripping used bychat.history, preventing<<<EXTERNAL_UNTRUSTED_CONTENT...>>>wrapper markup from rendering in Control UI chat. (#24012) Thanks @mittelaltergouda. - Telegram/Media: send a user-facing Telegram reply when media download fails (non-size errors) instead of silently dropping the message.
- Telegram/Webhook: keep webhook monitors alive until gateway abort signals fire, preventing false channel exits and immediate webhook auto-restart loops.
- Telegram/Polling: retry recoverable setup-time network failures in monitor startup and await runner teardown before retry to avoid overlapping polling sessions.
- Telegram/Polling: clear Telegram webhooks (
deleteWebhook) before starting long-pollgetUpdates, including retry handling for transient cleanup failures. - Telegram/Webhook: add
channels.telegram.webhookPortconfig support and pass it through plugin startup wiring to the monitor listener. - Browser/Extension Relay: refactor the MV3 worker to preserve debugger attachments across relay drops, auto-reconnect with bounded backoff+jitter, persist and rehydrate attached tab state via
chrome.storage.session, recover fromtarget_closednavigation detaches, guard stale socket handlers, enforce per-tab operation locks and per-request timeouts, and add lifecycle keepalive/badge refresh hooks (alarms,webNavigation). (#15099, #6175, #8468, #9807) - Browser/Relay: treat extension websocket as connected only when
OPEN, allow reconnect when a staleCLOSING/CLOSEDextension socket lingers, and guard stale socket message/close handlers so late events cannot clear active relay state; includes regression coverage for live-duplicate409rejection and immediate reconnect-after-close races. (#15099, #18698, #20688) - Browser/Remote CDP: extend stale-target recovery so
ensureTabAvailable()now reuses the sole available tab for remote CDP profiles (same behavior as extension profiles) while preserving stricttab not founderrors when multiple tabs exist; includes remote-profile regression tests. (#15989) - Gateway/Pairing: treat
operator.adminas satisfying otheroperator.*scope checks during device-auth verification so local CLI/TUI sessions stop entering pairing-required loops for pairing/approval-scoped commands. (#22062, #22193, #21191) Thanks @Botaccess, @jhartshorn, and @ctbritt. - Gateway/Pairing: auto-approve loopback
scope-upgradepairing requests (including device-token reconnects) so local clients do not disconnect on pairing-required scope elevation. (#23708) Thanks @widingmarcus-cyber. - Gateway/Scopes: include
operator.readandoperator.writein default operator connect scope bundles across CLI, Control UI, and macOS clients so write-scoped announce/sub-agent follow-up calls no longer hitpairing requireddisconnects on loopback gateways. (#22582) thanks @YuzuruS. - Gateway/Pairing: treat operator.admin pairing tokens as satisfying operator.write requests so legacy devices stop looping through scope-upgrade prompts introduced in 2026.2.19. (#23125, #23006) Thanks @vignesh07.
- Gateway/Restart: fix restart-loop edge cases by keeping
openclaw.mjs -> dist/entry.jsbootstrap detection explicit, reacquiring the gateway lock for in-process restart fallback paths, and tightening restart-loop regression coverage. (#23416) Thanks @jeffwnli. - Gateway/Lock: use optional gateway-port reachability as a primary stale-lock liveness signal (and wire gateway run-loop lock acquisition to the resolved port), reducing false "already running" lockouts after unclean exits. (#23760) Thanks @Operative-001.
- Delivery/Queue: quarantine queue entries immediately on known permanent delivery errors (for example invalid recipients or missing conversation references) by moving them to
failed/instead of retrying on every restart. (#23794) Thanks @aldoeliacim. - Cron/Status: split execution outcome (
lastRunStatus) from delivery outcome (lastDeliveryStatus) in persisted cron state, finished events, and run history so failed/unknown announcement delivery is visible without conflating it with run errors. - Cron/Delivery: route text-only announce jobs with explicit thread/topic targets through direct outbound delivery so forum/thread destinations do not get dropped by intermediary announce turns. (#23841) Thanks @AndrewArto.
- Cron: honor
cron.maxConcurrentRunsin the timer loop so due jobs can execute up to the configured parallelism instead of always running serially. (#11595) Thanks @Takhoffman. - Cron/Run: enforce the same per-job timeout guard for manual
cron.runexecutions as timer-driven runs, including abort propagation for isolated agent jobs, so forced runs cannot wedge indefinitely. (#23704) Thanks @tkuehnl. - Cron/Run: persist the manual-run
runningAtMsmarker before releasing the cron lock so overlapping timer ticks cannot start the same job concurrently. - Cron/Startup: enforce per-job timeout guards for startup catch-up replay runs so missed isolated jobs cannot hang indefinitely during gateway boot recovery.
- Cron/Main session: honor abort/timeout signals while retrying
wakeMode=nowheartbeat contention loops so main-target cron runs stop promptly instead of waiting through the full busy-retry window. - Cron/Schedule: for
everyjobs, preferlastRunAtMs + everyMswhen still in the future after restarts, then fall back to anchor scheduling for catch-up windows, so NEXT timing matches the last successful cadence. (#22895) Thanks @SidQin-cyber. - Cron/Service: execute manual
cron.runjobs outside the cron lock (while still persisting started/finished state atomically) socron.listandcron.statusremain responsive during long forced runs. (#23628) Thanks @dsgraves. - Cron/Timer: keep a watchdog recheck timer armed while
onTimeris actively executing so the scheduler continues polling even if a due-run tick stalls for an extended period. (#23628) Thanks @dsgraves. - Cron/Run log: clean up settled per-path run-log write queue entries so long-running cron uptime does not retain stale promise bookkeeping in memory.
- Cron/Isolation: force fresh session IDs for isolated cron runs so
sessionTarget="isolated"executions never reuse prior run context. (#23470) Thanks @echoVic. - Plugins/Install: strip
workspace:*devDependency entries from copied plugin manifests beforenpm install --omit=dev, preventingEUNSUPPORTEDPROTOCOLinstall failures for npm-published channel plugins (including Feishu and MS Teams). - Feishu/Plugins: restore bundled Feishu SDK availability for global installs and strip
openclaw: workspace:*from plugindevDependenciesduring plugin-version sync so npm-installed Feishu plugins do not fail dependency install. (#23611, #23645, #23603) - Config/Channels: auto-enable built-in channels by writing
channels.<id>.enabled=true(notplugins.entries.<id>), and stop adding built-ins toplugins.allow, preventingplugins.entries.telegram: plugin not foundvalidation failures. - Config/Channels: when
plugins.allowis active, auto-enable/enable flows now also allowlist configured built-in channels sochannels.<id>.enabled=truecannot remain blocked by restrictive plugin allowlists. - Plugins/Discovery: ignore scanned extension backup/disabled directory patterns (for example
.backup-*,.bak,.disabled*) and move updater backup directories under.openclaw-install-backups, preventing duplicate plugin-id collisions from archived copies. - Plugins/CLI: make
openclaw plugins enableand plugin install/link flows update allowlists via shared plugin-enable policy so enabled plugins are not left disabled by allowlist mismatch. (#23190) Thanks @downwind7clawd-ctrl. - Security/Voice Call: harden media stream WebSocket handling against pre-auth idle-connection DoS by adding strict pre-start timeouts, pending/per-IP connection limits, and total connection caps for streaming endpoints. This ships in the next npm release. Thanks @jiseoung for reporting.
- Security/Sessions: redact sensitive token patterns from
sessions_historytool output and surfacecontentRedactedmetadata when masking occurs. (#16928) Thanks @aether-ai-agent. - Security/Exec: stop trusting
PATH-derived directories for safe-bin allowlist checks, add explicittools.exec.safeBinTrustedDirs, and pin safe-bin shell execution to resolved absolute executable paths to prevent binary-shadowing approval bypasses. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Elevated: match
tools.elevated.allowFromagainst sender identities only (not recipientctx.To), closing a recipient-token bypass for/elevatedauthorization. This ships in the next npm release. Thanks @jiseoung for reporting. - Security/Feishu: enforce ID-only allowlist matching for DM/group sender authorization, normalize Feishu ID prefixes during checks, and ignore mutable display names so display-name collisions cannot satisfy allowlist entries. This ships in the next npm release. Thanks @jiseoung for reporting.
- Security/Group policy: harden
channels.*.groups.*.toolsBySendermatching by requiring explicit sender-key types (id:,e164:,username:,name:), preventing cross-identifier collisions across mutable/display-name fields while keeping legacy untyped keys on a deprecated ID-only path. This ships in the next npm release. Thanks @jiseoung for reporting. - Channels/Group policy: fail closed when
groupPolicy: "allowlist"is set without explicitgroups, honor account-levelgroupPolicyoverrides, and enforcegroupPolicy: "disabled"as a hard group block. (#22215) Thanks @etereo. - Telegram/Discord extensions: propagate trusted
mediaLocalRootsthrough extension outboundsendMediaoptions so extension direct-send media paths honor agent-scoped local-media allowlists. (#20029, #21903, #23227) - Agents/Exec: honor explicit agent context when resolving
tools.execdefaults for runs with opaque/non-agent session keys, so per-agenthost/security/askpolicies are applied consistently. (#11832) - Doctor/Security: add an explicit warning that
approvals.exec.enabled=falsedisables forwarding only, while enforcement remains driven by host-localexec-approvals.jsonpolicy. (#15047) - Sandbox/Docker: default sandbox container user to the workspace owner
uid:gidwhenagents.*.sandbox.docker.useris unset, fixing non-root gateway file-tool permissions under capability-dropped containers. (#20979) - Plugins/Media sandbox: propagate trusted
mediaLocalRootsthrough plugin action dispatch (including Discord/Telegram action adapters) so plugin send paths enforce the same agent-scoped local-media sandbox roots as core outbound sends. (#20258, #22718) - Agents/Workspace guard: map sandbox container-workdir file-tool paths (for example
/workspace/...andfile:///workspace/...) to host workspace roots before workspace-only validation, preventing falsePath escapes sandbox rootrejections for sandbox file tools. (#9560) - Gateway/Exec approvals: expire approval requests immediately when no approval-capable gateway clients are connected and no forwarding targets are available, avoiding delayed approvals after restarts/offline approver windows. (#22144)
- Security/Exec approvals: when approving wrapper commands with allow-always in allowlist mode, persist inner executable paths for known dispatch wrappers (
env,nice,nohup,stdbuf,timeout) and fail closed (no persisted entry) when wrapper unwrapping is not safe, preventing wrapper-path approval bypasses. Thanks @tdjackey for reporting. - Node/macOS exec host: default headless macOS node
system.runto local execution and only route through the companion app whenOPENCLAW_NODE_EXEC_HOST=appis explicitly set, avoiding companion-app filesystem namespace mismatches during exec. (#23547) - Sandbox/Media: map container workspace paths (
/workspace/...andfile:///workspace/...) back to the host sandbox root for outbound media validation, preventing false deny errors for sandbox-generated local media. (#23083) Thanks @echo931. - Sandbox/Docker: apply custom bind mounts after workspace mounts and prioritize bind-source resolution on overlapping paths, so explicit workspace binds are no longer ignored. (#22669) Thanks @tasaankaeris.
- Exec approvals/Forwarding: restore Discord text forwarding when component approvals are not configured, and carry request snapshots through resolve events so resolved notices still forward after cache misses/restarts. (#22988) Thanks @bubmiller.
- Control UI/WebSocket: stop and clear the browser gateway client on UI teardown so remounts cannot leave orphan websocket clients that create duplicate active connections. (#23422) Thanks @floatinggball-design.
- Control UI/WebSocket: send a stable per-tab
instanceIdin websocket connect frames so reconnect cycles keep a consistent client identity for diagnostics and presence tracking. (#23616) Thanks @zq58855371-ui. - Config/Memory: allow
"mistral"inagents.defaults.memorySearch.providerandagents.defaults.memorySearch.fallbackschema validation. (#14934) Thanks @ThomsenDrake. - Feishu/Commands: in group chats, command authorization now falls back to top-level
channels.feishu.allowFromwhen per-groupallowFromis not set, so/commandno longer gets blocked by an unintended empty allowlist. (#23756) - Dev tooling: prevent
CLAUDE.mdsymlink target regressions by excluding CLAUDE symlink sentinels fromoxfmtand marking them-textin.gitattributes, so formatter/EOL normalization cannot reintroduce trailing-newline targets. Thanks @vincentkoc. - Agents/Compaction: restore embedded compaction safeguard/context-pruning extension loading in production by wiring bundled extension factories into the resource loader instead of runtime file-path resolution. (#22349) Thanks @Glucksberg.
- Feishu/Media: for inbound video messages that include both
file_key(video) andimage_key(thumbnail), preferfile_keywhen downloading media so video attachments are saved instead of silently failing on thumbnail keys. (#23633) - Hooks/Loader: avoid redundant hook-module recompilation on gateway restart by skipping cache-busting for bundled hooks and using stable file metadata keys (
mtime+size) for mutable workspace/managed/plugin hook imports. (#16953) Thanks @mudrii. - Hooks/Cron: suppress duplicate main-session events for delivered hook turns and mark
SILENT_REPLY_TOKEN(NO_REPLY) early exits as delivered to prevent hook context pollution. (#20678) Thanks @JonathanWorks. - Providers/OpenRouter: inject
cache_controlon system prompts for OpenRouter Anthropic models to improve prompt-cache reuse. (#17473) Thanks @rrenamed. - Installer/Smoke tests: remove legacy
OPENCLAW_USE_GUMoverrides from docker install-smoke runs so tests exercise installer auto TTY detection behavior directly. - Providers/OpenRouter: allow pass-through OpenRouter and Opencode model IDs in live model filtering so custom routed model IDs are treated as modern refs. (#14312) Thanks @Joly0.
- Providers/OpenRouter: default reasoning to enabled when the selected model advertises
reasoning: trueand no session/directive override is set. (#22513) Thanks @zwffff. - Providers/OpenRouter: map
/thinklevels toreasoning.effortin embedded runs while preserving explicitreasoning.max_tokenspayloads. (#17236) Thanks @robbyczgw-cla. - Providers/OpenRouter: preserve stored session provider when model IDs are vendor-prefixed (for example,
anthropic/...) so follow-up turns do not incorrectly route to direct provider APIs. (#22753) Thanks @dndodson. - Providers/OpenRouter: preserve the required
openrouter/prefix for OpenRouter-native model IDs during model-ref normalization. (#12942) Thanks @omair445. - Providers/OpenRouter: pass through provider routing parameters from model params.provider to OpenRouter request payloads for provider selection controls. (#17148) Thanks @carrotRakko.
- Providers/OpenRouter: preserve model allowlist entries containing OpenRouter preset paths (for example
openrouter/@preset/...) by treating/model ...@profileauth-profile parsing as a suffix-only override. (#14120) Thanks @NotMainstream. - Cron/Auth: propagate auth-profile resolution to isolated cron sessions so provider API keys are resolved the same way as main sessions, fixing 401 errors when using providers configured via auth-profiles. (#20689) Thanks @lailoo.
- Cron/Follow-up: pass resolved
agentDirthrough isolated cron and queued follow-up embedded runs so auth/profile lookups stay scoped to the correct agent directory. (#22845) Thanks @seilk. - Agents/Media: route tool-result
MEDIA:extraction through shared parser validation so malformed prose likeMEDIA:-prefixed ...is no longer treated as a local file path (prevents Telegram ENOENT tool-error overrides). (#18780) Thanks @HOYALIM. - Logging: cap single log-file size with
logging.maxFileBytes(default 500 MB) and suppress additional writes after cap hit to prevent disk exhaustion from repeated error storms. - Memory/Remote HTTP: centralize remote memory HTTP calls behind a shared guarded helper (
withRemoteHttpResponse) so embeddings and batch flows use one request/release path. - Memory/Embeddings: apply configured remote-base host pinning (
allowedHostnames) across OpenAI/Voyage/Gemini embedding requests to keep private/self-hosted endpoints working without cross-host drift. (#18198) Thanks @ianpcook. - Memory/Batch: route OpenAI/Voyage/Gemini batch upload/create/status/download requests through the same guarded HTTP path for consistent SSRF policy enforcement.
- Memory/Index: detect memory source-set changes (for example enabling
sessionsafter an existing memory-only index) and trigger a full reindex so existing session transcripts are indexed without requiring--force. (#17576) Thanks @TarsAI-Agent. - Memory/Embeddings: enforce a per-input 8k safety cap before embedding batching and apply a conservative 2k fallback limit for local providers without declared input limits, preventing oversized session/memory chunks from triggering provider context-size failures during sync/indexing. (#6016) Thanks @batumilove.
- Memory/QMD: on Windows, resolve bare
qmd/mcportercommand names to npm shim executables (.cmd) before spawning, so qmd boot updates and mcporter-backed searches no longer fail withspawn ... ENOENTon default npm installs. (#23899) Thanks @arcbuilder-ai. - Memory/QMD: parse plain-text
qmd collection list --jsonoutput when older qmd builds ignore JSON mode, and retry memory searches once after re-ensuring managed collections when qmd returnsCollection not found .... (#23613) Thanks @leozhucn. - Signal/RPC: guard malformed Signal RPC JSON responses with a clear status-scoped error and add regression coverage for invalid JSON responses. (#22995) Thanks @adhitShet.
- Gateway/Subagents: guard gateway and subagent session-key/message trim paths against undefined inputs to prevent early
Cannot read properties of undefined (reading 'trim')crashes during subagent spawn and wait flows. - Agents/Workspace: guard
resolveUserPathagainst undefined/null input to preventCannot read properties of undefined (reading 'trim')crashes when workspace paths are missing in embedded runner flows. - Auth/Profiles: keep active
cooldownUntil/disabledUntilwindows immutable across retries so mid-window failures cannot extend recovery indefinitely; only recompute a backoff window after the previous deadline has expired. This resolves cron/inbound retry loops that could trap gateways until manualusageStatscleanup. (#23516, #23536) Thanks @arosstale. - Channels/Security: fail closed on missing provider group policy config by defaulting runtime group policy to
allowlist(instead of inheritingchannels.defaults.groupPolicy) whenchannels.<provider>is absent across message channels, and align runtime + security warnings/docs to the same fallback behavior (Slack, Discord, iMessage, Telegram, WhatsApp, Signal, LINE, Matrix, Mattermost, Google Chat, IRC, Nextcloud Talk, Feishu, and Zalo user flows; plus Discord message/native-command paths). (#23367) Thanks @bmendonca3. - Gateway/Onboarding: harden remote gateway onboarding defaults and guidance by defaulting discovered direct URLs to
wss://, rejecting insecure non-loopbackws://targets in onboarding validation, and expanding remote-security remediation messaging across gateway client/call/doctor flows. (#23476) Thanks @bmendonca3. - CLI/Sessions: pass the configured sessions directory when resolving transcript paths in
agentCommand, so customsession.storelocations resume sessions reliably. Thanks @davidrudduck. - Signal/Monitor: treat user-initiated abort shutdowns as clean exits when auto-started
signal-cliis terminated, while still surfacing unexpected daemon exits as startup/runtime failures. (#23379) Thanks @frankekn. - Channels/Dedupe: centralize plugin dedupe primitives in plugin SDK (memory + persistent), move Feishu inbound dedupe to a namespace-scoped persistent store, and reuse shared dedupe cache logic for Zalo webhook replay + Tlon processed-message tracking to reduce duplicate handling during reconnect/replay paths. (#23377) Thanks @SidQin-cyber.
- Channels/Delivery: remove hardcoded WhatsApp delivery fallbacks; require explicit/session channel context or auto-pick the sole configured channel when unambiguous. (#23357) Thanks @lbo728.
- ACP/Gateway: wait for gateway hello before opening ACP requests, and fail fast on pre-hello connect failures to avoid startup hangs and early
gateway not connectedrequest races. (#23390) Thanks @janckerchen. - Gateway/Auth: preserve
OPENCLAW_GATEWAY_PASSWORDenv override precedence for remote gateway call credentials after shared resolver refactors, preventing stale configured remote passwords from overriding runtime secret rotation. - Gateway/Auth: preserve shared-token
gateway token mismatchauth errors whenauth.tokenfallback device-token checks fail, and reservedevice token mismatchguidance for explicitauth.deviceTokenfailures. - Gateway/Tools: when agent tools pass an allowlisted
gatewayUrloverride, resolve local override tokens from env/config fallback but keep remote overrides strict togateway.remote.token, preventing local token leakage to remote targets. - Gateway/Client: keep cached device-auth tokens on
device token mismatchcloses when the client used explicit shared token/password credentials, avoiding accidental pairing-token churn during explicit-auth failures. - Node host/Exec: keep strict Windows allowlist behavior for
cmd.exe /cshell-wrapper runs, and return explicit approval guidance when blocked (SYSTEM_RUN_DENIED: allowlist miss). - Control UI: show pairing-required guidance (commands + mobile tokenized URL reminder) when the dashboard disconnects with
1008 pairing required. - Security/Audit: add
openclaw security auditdetection for open group policies that expose runtime/filesystem tools without sandbox/workspace guards (security.exposure.open_groups_with_runtime_or_fs). - Security/Audit: make
gateway.real_ip_fallback_enabledseverity conditional for loopback trusted-proxy setups (warn for loopback-onlytrustedProxies, critical when non-loopback proxies are trusted). (#23428) Thanks @bmendonca3. - Security/Exec env: block request-scoped
HOMEandZDOTDIRoverrides in host exec env sanitizers (Node + macOS), preventing shell startup-file execution before allowlist-evaluated command bodies. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Exec env: block
SHELLOPTS/PS4in host exec env sanitizers and restrict shell-wrapper (bash|sh|zsh ... -c/-lc) request env overrides to a small explicit allowlist (TERM,LANG,LC_*,COLORTERM,NO_COLOR,FORCE_COLOR) on both node host and macOS companion paths, preventing xtrace prompt command-substitution allowlist bypasses. This ships in the next npm release. Thanks @tdjackey for reporting. - WhatsApp/Security: enforce
allowFromfor direct-message outbound targets in all send modes (includingmode: "explicit"), preventing sends to non-allowlisted numbers. (#20108) Thanks @zahlmann. - Security/Exec approvals: fail closed on shell line continuations (
\\\n/\\\r\n) and treat shell-wrapper execution as approval-required in allowlist mode, preventing$\\newline command-substitution bypasses. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Gateway: emit a startup security warning when insecure/dangerous config flags are enabled (including
gateway.controlUi.dangerouslyDisableDeviceAuth=true) and point operators toopenclaw security audit. - Security/Hooks auth: normalize hook auth rate-limit client IP keys so IPv4 and IPv4-mapped IPv6 addresses share one throttle bucket, preventing dual-form auth-attempt budget bypasses. This ships in the next npm release. Thanks @aether-ai-agent for reporting.
- Security/Exec approvals: treat
envand shell-dispatch wrappers as transparent during allowlist analysis on node-host and macOS companion paths so policy checks match the effective executable/inline shell payload instead of the wrapper binary, blocking wrapper-smuggled allowlist bypasses. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Exec approvals: require explicit safe-bin profiles for
tools.exec.safeBinsentries in allowlist mode (remove generic safe-bin profile fallback), and addtools.exec.safeBinProfilesfor safe custom binaries so unprofiled interpreter-style entries cannot be treated as stdin-safe. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Channels: harden Slack external menu token handling by switching to CSPRNG tokens, validating token shape, requiring user identity for external option lookups, and avoiding fabricated timestamp
trigger_idfallbacks; also switch Tlon Urbit channel IDs to CSPRNG UUIDs, centralize secure ID/token generation via shared infra helpers, and add a guardrail test to block new runtimeDate.now()+Math.random()token/id patterns. - Security/Hooks transforms: enforce symlink-safe containment for webhook transform module paths (including
hooks.transformsDirandhooks.mappings[].transform.module) by resolving existing-path ancestors via realpath before import, while preserving in-root symlink support; add regression coverage for both escape and allow cases. This ships in the next npm release. Thanks @aether-ai-agent for reporting. - Telegram/WSL2: disable
autoSelectFamilyby default on WSL2 and memoize WSL2 detection in Telegram network decision logic to avoid repeated sync/proc/versionprobes on fetch/send paths. (#21916) Thanks @MizukiMachine. - Telegram/Network: default Node 22+ DNS result ordering to
ipv4firstfor Telegram fetch paths and addOPENCLAW_TELEGRAM_DNS_RESULT_ORDER/channels.telegram.network.dnsResultOrderoverrides to reduce IPv6-path fetch failures. (#5405) Thanks @Glucksberg. - Telegram/Forward bursts: coalesce forwarded text+media updates through a dedicated forward lane debounce window that works with default inbound debounce config, while keeping forwarded control commands immediate. (#19476) thanks @napetrov.
- Telegram/Streaming: preserve archived draft preview mapping after flush and clean superseded reasoning preview bubbles so multi-message preview finals no longer cross-edit or orphan stale messages under send/rotation races. (#23202) Thanks @obviyus.
- Telegram/Replies: scope messaging-tool text/media dedupe to same-target sends only, so cross-target tool sends can no longer silently suppress Telegram final replies.
- Telegram/Replies: normalize
file://and local-path media variants during messaging dedupe so equivalent media paths do not produce duplicate Telegram replies. - Telegram/Replies: extract forwarded-origin context from unified reply targets (
reply_to_messageandexternal_reply) so forward+comment metadata is preserved across partial reply shapes. (#9720) thanks @mcaxtr. - Telegram/Polling: persist a safe update-offset watermark bounded by pending updates so crash/restart cannot skip queued lower
update_idupdates after out-of-order completion. (#23284) thanks @frankekn. - Telegram/Polling: force-restart stuck runner instances when recoverable unhandled network rejections escape the polling task path, so polling resumes instead of silently stalling. (#19721) Thanks @jg-noncelogic.
- Slack/Slash commands: preserve the Bolt app receiver when registering external select options handlers so monitor startup does not crash on runtimes that require bound
app.optionscalls. (#23209) Thanks @0xgaia. - Slack/Telegram slash sessions: await session metadata persistence before dispatch so first-turn native slash runs do not race session-origin metadata updates. (#23065) thanks @hydro13.
- Slack/Queue routing: preserve string
thread_tsvalues through collect-mode queue drain and DMdeliveryContextupdates so threaded follow-ups do not leak to the main channel when Slack thread IDs are strings. (#11934) Thanks @sandieman2 and @vincentkoc. - Telegram/Native commands: set
ctx.Provider="telegram"for native slash-command context so elevated gate checks resolve provider correctly (fixesprovider (ctx.Provider)failures in/elevatedflows). (#23748) Thanks @serhii12. - Agents/Ollama: preserve unsafe integer tool-call arguments as exact strings during NDJSON parsing, preventing large numeric IDs from being rounded before tool execution. (#23170) Thanks @BestJoester.
- Cron/Gateway: keep
cron.listandcron.statusresponsive during startup catch-up by avoiding a long-held cron lock while missed jobs execute. (#23106) Thanks @jayleekr. - Gateway/Config reload: compare array-valued config paths structurally during diffing so unchanged
memory.qmd.pathsandmemory.qmd.scope.rulesno longer trigger false restart-required reloads. (#23185) Thanks @rex05ai. - Gateway/Config reload: retry short-lived missing config snapshots during reload before skipping, preventing atomic-write unlink windows from triggering restart loops. (#23343) Thanks @lbo728.
- Cron/Scheduling: validate runtime cron expressions before schedule/stagger evaluation so malformed persisted jobs report a clear
invalid cron schedule: expr is requirederror instead of crashing withundefined.trimfailures and auto-disable churn. (#23223) Thanks @asimons81. - Memory/QMD: migrate legacy unscoped collection bindings (for example
memory-root) to per-agent scoped names (for examplememory-root-main) during startup when safe, so QMD-backedmemory_searchno longer fails withCollection not foundafter upgrades. (#23228, #20727) Thanks @JLDynamics and @AaronFaby. - Memory/QMD: normalize Han-script BM25 search queries before invoking
qmd searchso mixed CJK+Latin prompts no longer return empty results due to tokenizer mismatch. (#23426) Thanks @LunaLee0130. - TUI/Input: enable multiline-paste burst coalescing on macOS Terminal.app and iTerm so pasted blocks no longer submit line-by-line as separate messages. (#18809) Thanks @fwends.
- TUI/RTL: isolate right-to-left script lines (Arabic/Hebrew ranges) with Unicode bidi isolation marks in TUI text sanitization so RTL assistant output no longer renders in reversed visual order in terminal chat panes. (#21936) Thanks @Asm3r96.
- TUI/Status: request immediate renders after setting
sending/waitingactivity states so in-flight runs always show visible progress indicators instead of appearing idle until completion. (#21549) Thanks @13Guinness. - TUI/Input: arm Ctrl+C exit timing when clearing non-empty composer text and add a SIGINT fallback path so double Ctrl+C exits remain responsive during active runs instead of requiring an extra press or appearing stuck. (#23407) Thanks @tinybluedev.
- Agents/Fallbacks: treat JSON payloads with
type: "api_error"+"Internal server error"as transient failover errors so Anthropic 500-style failures trigger model fallback. (#23193) Thanks @jarvis-lane. - Agents/Google: sanitize non-base64
thought_signature/thoughtSignaturevalues from assistant replay transcripts for native Google Gemini requests while preserving valid signatures and tool-call order. (#23457) Thanks @echoVic. - Agents/Transcripts: validate assistant tool-call names (syntax/length + registered tool allowlist) before transcript persistence and during replay sanitization so malformed failover tool names no longer poison sessions with repeated provider HTTP 400 errors. (#23324) Thanks @johnsantry.
- Agents/Mistral: sanitize tool-call IDs in the embedded agent loop and generate strict provider-safe pending tool-call IDs, preventing Mistral strict9
HTTP 400failures on tool continuations. (#23698) Thanks @echoVic. - Agents/Compaction: strip stale assistant usage snapshots from pre-compaction turns when replaying history after a compaction summary so context-token estimation no longer reuses pre-compaction totals and immediately re-triggers destructive follow-up compactions. (#19127) Thanks @tedwatson.
- Agents/Replies: emit a default completion acknowledgement (
✅ Done.) only for direct/private tool-only completions with no final assistant text, while suppressing synthetic acknowledgements for channel/group sessions and runs that already delivered output via messaging tools. (#22834) Thanks @Oldshue. - Agents/Subagents: honor
tools.subagents.tools.alsoAllowand explicit subagentallowentries when resolving built-in subagent deny defaults, so explicitly granted tools (for examplesessions_send) are no longer blocked unless re-denied intools.subagents.tools.deny. (#23359) Thanks @goren-beehero. - Agents/Subagents: make announce call timeouts configurable via
agents.defaults.subagents.announceTimeoutMsand restore a 60s default to prevent false timeout failures on slower announce paths. (#22719) Thanks @Valadon. - Agents/Diagnostics: include resolved lifecycle error text in
embedded run agent endwarnings so UI/TUI “Connection error” runs expose actionable provider failure reasons in gateway logs. (#23054) Thanks @Raize. - Agents/Auth profiles: skip auth-profile cooldown writes for timeout failures in embedded runner rotation so model/network timeouts do not poison same-provider fallback model selection while still allowing in-turn account rotation. (#22622) Thanks @vageeshkumar.
- Plugins/Hooks: run legacy
before_agent_startonce per agent turn and reuse that result across model-resolve and prompt-build compatibility paths, preventing duplicate hook side effects (for example duplicate external API calls). (#23289) Thanks @ksato8710. - Models/Config: default missing Anthropic provider/model
apifields toanthropic-messagesduring config validation so custom relay model entries are preserved instead of being dropped by runtime model registry validation. (#23332) Thanks @bigbigmonkey123. - Gateway/Pairing: preserve existing approved token scopes when processing repair pairings that omit
scopes, preventing empty-scope token regressions on reconnecting clients. (#21906) Thanks @paki81. - Memory/QMD: add optional
memory.qmd.mcportersearch routing so QMDquery/search/vsearchcan run through mcporter keep-alive flows (including multi-collection paths) to reduce cold starts, while keeping searches on agent-scoped QMD state for consistent recall. (#19617) Thanks @nicole-luxe and @vignesh07. - Infra/Network: classify undici
TypeError: fetch failedas transient in unhandled-rejection detection even when nested causes are unclassified, preventing avoidable gateway crash loops on flaky networks. (#14345) Thanks @Unayung. - Telegram/Retry: classify undici
TypeError: fetch failedas recoverable in both polling and send retry paths so transient fetch failures no longer fail fast. (#16699) thanks @Glucksberg. - Docs/Telegram: correct Node 22+ network defaults (
autoSelectFamily,dnsResultOrder) and clarify Telegram setup does not use positionalopenclaw channels login telegram. (#23609) Thanks @ryanbastic. - BlueBubbles/DM history: restore DM backfill context with account-scoped rolling history, bounded backfill retries, and safer history payload limits. (#20302) Thanks @Ryan-Haines.
- BlueBubbles/Private API cache: treat unknown (
null) private-API cache status as disabled for send/attachment/reply flows to avoid stale-cache 500s, and log a warning when reply/effect features are requested while capability is unknown. (#23459) Thanks @echoVic. - BlueBubbles/Webhooks: accept inbound/reaction webhook payloads when BlueBubbles omits
handlebut provides DMchatGuid, and harden payload extraction for array/string-wrapped message bodies so valid webhook events no longer get rejected as unparseable. (#23275) Thanks @toph31. - Security/Audit: add
openclaw security auditfindinggateway.nodes.allow_commands_dangerousfor riskygateway.nodes.allowCommandsoverrides, with severity upgraded to critical on remote gateway exposure. - Gateway/Control plane: reduce cross-client write limiter contention by adding
connIdfallback keying when device ID and client IP are both unavailable. - Security/Config: block prototype-key traversal during config merge patch and legacy migration merge helpers (
__proto__,constructor,prototype) to prevent prototype pollution during config mutation flows. (#22968) Thanks @Clawborn. - Security/Shell env: validate login-shell executable paths for shell-env fallback (
/etc/shells+ trusted prefixes), blockSHELL/HOME/ZDOTDIRin config env ingestion before fallback execution, and sanitize fallback shell exec env to pinHOMEto the real user home while droppingZDOTDIRand other dangerous startup vars. This ships in the next npm release. Thanks @tdjackey for reporting. - Network/SSRF: enable
autoSelectFamilyon pinned undici dispatchers (with attempt timeout) so IPv6-unreachable environments can quickly fall back to IPv4 for guarded fetch paths. (#19950) Thanks @ENAwareness. - Security/Config: make parsed chat allowlist checks fail closed when
allowFromis empty, restoring expected DM/pairing gating. - Security/Exec: in non-default setups that manually add
sorttotools.exec.safeBins, blocksort --compress-programso allowlist-mode safe-bin checks cannot bypass approval. Thanks @tdjackey for reporting. - Security/Exec approvals: when users choose
allow-alwaysfor shell-wrapper commands (for example/bin/zsh -lc ...), persist allowlist patterns for the inner executable(s) instead of the wrapper shell binary, preventing accidental broad shell allowlisting in moderate mode. (#23276) Thanks @xrom2863. - Security/Exec: fail closed when
tools.exec.host=sandboxis configured/requested but sandbox runtime is unavailable. (#23398) Thanks @bmendonca3. - Security/macOS app beta: enforce path-only
system.runallowlist matching (drop basename matches likeecho), migrate legacy basename entries to last resolved paths when available, and harden shell-chain handling to fail closed on unsafe parse/control syntax (including quoted command substitution/backticks). This is an optional allowlist-mode feature; default installs remain deny-by-default. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Agents: auto-generate and persist a dedicated
commands.ownerDisplaySecretwhencommands.ownerDisplay=hash, remove gateway token fallback from owner-ID prompt hashing across CLI and embedded agent runners, and centralize owner-display secret resolution in one shared helper. This ships in the next npm release. Thanks @aether-ai-agent for reporting. - Security/SSRF: expand IPv4 fetch guard blocking to include RFC special-use/non-global ranges (including benchmarking, TEST-NET, multicast, and reserved/broadcast blocks), centralize range checks into a single CIDR policy table, and reuse one shared host/IP classifier across literal + DNS checks to reduce classifier drift. This ships in the next npm release. Thanks @princeeismond-dot for reporting.
- Security/SSRF: block RFC2544 benchmarking range (
198.18.0.0/15) across direct and embedded-IP paths, and normalize IPv6 dotted-quad transition literals (for example::127.0.0.1,64:ff9b::8.8.8.8) in shared IP parsing/classification. - Security/Archive: block zip symlink escapes during archive extraction.
- Security/Media sandbox: keep tmp media allowance for absolute tmp paths only and enforce symlink-escape checks before sandbox-validated reads, preventing tmp symlink exfiltration and relative
../sandbox escapes when sandboxes live under tmp. (#17892) Thanks @dashed. - Browser/Upload: accept canonical in-root upload paths when the configured uploads directory is a symlink alias (for example
/tmp->/private/tmpon macOS), so browser upload validation no longer rejects valid files during client->server revalidation. (#23300, #23222, #22848) Thanks @bgaither4, @parkerati, and @Nabsku. - Security/Discord: add
openclaw security auditwarnings for name/tag-based Discord allowlist entries (DM allowlists, guild/channelusers, and pairing-store entries), highlighting slug-collision risk while keeping name-based matching supported, and canonicalize resolved Discord allowlist names to IDs at runtime without rewriting config files. Thanks @tdjackey for reporting. - Security/Gateway: block node-role connections when device identity metadata is missing.
- Security/Media: enforce inbound media byte limits during download/read across Discord, Telegram, Zalo, Microsoft Teams, and BlueBubbles to prevent oversized payload memory spikes before rejection. This ships in the next npm release. Thanks @tdjackey for reporting.
- Media/Understanding: preserve
application/pdfMIME classification during text-like file heuristics so PDF uploads use PDF extraction paths instead of being inlined as raw text. (#23191) Thanks @claudeplay2026-byte. - Security/Control UI: block symlink-based out-of-root static file reads by enforcing realpath containment and file-identity checks when serving Control UI assets and SPA fallback
index.html. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Gateway avatars: block symlink traversal during local avatar
data:URL resolution by enforcing realpath containment and file-identity checks before reads. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/Control UI: centralize avatar URL/path validation across gateway/config helpers and enforce a 2 MB max size for local agent avatar files before
/avatarresolution, reducing oversized-avatar memory risk without changing supported avatar formats. - Security/Control UI avatars: harden
/avatar/:agentIdlocal avatar serving by rejecting symlink paths and requiring fd-level file identity + size checks before reads. This ships in the next npm release. Thanks @tdjackey for reporting. - Security/MSTeams media: enforce allowlist checks for SharePoint reference attachment URLs and redirect targets during Graph-backed media fetches so redirect chains cannot escape configured media host boundaries. This ships in the next npm release. Thanks @tdjackey for reporting.
- Security/MSTeams media: route attachment auth-retry and Graph SharePoint download redirects through shared
safeFetchso each hop is validated with allowlist + DNS/IP checks across the full redirect chain. (#23598) Thanks @Asm3r96 and @lewiswigmore. - Security/macOS discovery: fail closed for unresolved discovery endpoints by clearing stale remote selection values, use resolved service host only for SSH target derivation, and keep remote URL config aligned with resolved endpoint availability. (#21618) Thanks @bmendonca3.
- Chat/Usage/TUI: strip synthetic inbound metadata blocks (including
Conversation infoand trailingUntrusted contextchannel metadata wrappers) from displayed conversation history so internal prompt context no longer leaks into user-visible logs. - CI/Tests: fix TypeScript case-table typing and lint assertion regressions so
pnpm checkpasses again after Synology Chat landing. (#23012) Thanks @druide67. - Security/Browser relay: harden extension relay auth token handling for
/extensionand/cdppathways. - Cron: persist
deliveredstate in cron job records so delivery failures remain visible in status and logs. (#19174) Thanks @simonemacario. - Config/Doctor: only repair the OAuth credentials directory when affected channels are configured, avoiding fresh-install noise.
- Config/Channels: whitelist
channels.modelByChannelin config validation and exclude it from plugin auto-enable channel detection so model overrides no longer triggerunknown channel idvalidation errors or bogusmodelByChannelplugin enables. (#23412) Thanks @ProspectOre. - Config/Bindings: allow optional
bindings[].commentin strict config validation so annotated binding entries no longer fail load. (#23458) Thanks @echoVic. - Usage/Pricing: correct MiniMax M2.5 pricing defaults to fix inflated cost reporting. (#22755) Thanks @miloudbelarebia.
- Gateway/Daemon: verify gateway health after daemon restart.
- Agents/UI text: stop rewriting normal assistant billing/payment language outside explicit error contexts. (#17834) Thanks @niceysam.
npm patch deltas (post-release)
-
2026.2.22-1- Gateway/Chat UI: sanitize untrusted wrapper markup in final payloads.
-
2026.2.22-2- Cron: preserve due jobs after manual runs. (#23994)
- Exec: keep implicit sandbox default and restore the no-alert baseline (no approval popup by default unless host is explicitly configured to
gateway/node).