Releases: openclaw/openclaw
Releases · openclaw/openclaw
openclaw 2026.3.2
Immutable
release. Only release title and notes can be modified.
Changes
- Secrets/SecretRef coverage: expand SecretRef support across the full supported user-supplied credential surface (64 targets total), including runtime collectors,
openclaw secretsplanning/apply/audit flows, onboarding SecretInput UX, and related docs; unresolved refs now fail fast on active surfaces while inactive surfaces report non-blocking diagnostics. (#29580) Thanks @joshavant. - Tools/PDF analysis: add a first-class
pdftool with native Anthropic and Google PDF provider support, extraction fallback for non-native models, configurable defaults (agents.defaults.pdfModel,pdfMaxBytesMb,pdfMaxPages), and docs/tests covering routing, validation, and registration. (#31319) Thanks @tyler6204. - Outbound adapters/plugins: add shared
sendPayloadsupport across direct-text-media, Discord, Slack, WhatsApp, Zalo, and Zalouser with multi-media iteration and chunk-aware text fallback. (#30144) Thanks @nohat. - Models/MiniMax: add first-class
MiniMax-M2.5-highspeedsupport across built-in provider catalogs, onboarding flows, and MiniMax OAuth plugin defaults, while keeping legacyMiniMax-M2.5-Lightningcompatibility for existing configs. - Sessions/Attachments: add inline file attachment support for
sessions_spawn(subagent runtime only) with base64/utf8 encoding, transcript content redaction, lifecycle cleanup, and configurable limits viatools.sessions_spawn.attachments. (#16761) Thanks @napetrov. - Telegram/Streaming defaults: default
channels.telegram.streamingtopartial(fromoff) so new Telegram setups get live preview streaming out of the box, with runtime fallback to message-edit preview when native drafts are unavailable. - Telegram/DM streaming: use
sendMessageDraftfor private preview streaming, keep reasoning/answer preview lanes separated in DM reasoning-stream mode. (#31824) Thanks @obviyus. - Telegram/voice mention gating: add optional
disableAudioPreflighton group/topic config to skip mention-detection preflight transcription for inbound voice notes where operators want text-only mention checks. (#23067) Thanks @yangnim21029. - CLI/Config validation: add
openclaw config validate(with--json) to validate config files before gateway startup, and include detailed invalid-key paths in startup invalid-config errors. (#31220) thanks @Sid-Qin. - Tools/Diffs: add PDF file output support and rendering quality customization controls (
fileQuality,fileScale,fileMaxWidth) for generated diff artifacts, and document PDF as the preferred option when messaging channels compress images. (#31342) Thanks @gumadeiras. - Memory/Ollama embeddings: add
memorySearch.provider = "ollama"andmemorySearch.fallback = "ollama"support, honormodels.providers.ollamasettings for memory embedding requests, and document Ollama embedding usage. (#26349) Thanks @nico-hoff. - Zalo Personal plugin (
@openclaw/zalouser): rebuilt channel runtime to use nativezca-jsintegration in-process, removing external CLI transport usage and keeping QR/login + send/listen flows fully inside OpenClaw. - Plugin SDK/channel extensibility: expose
channelRuntimeonChannelGatewayContextso external channel plugins can access shared runtime helpers (reply/routing/session/text/media/commands) without internal imports. (#25462) Thanks @guxiaobo. - Plugin runtime/STT: add
api.runtime.stt.transcribeAudioFile(...)so extensions can transcribe local audio files through OpenClaw's configured media-understanding audio providers. (#22402) Thanks @benthecarman. - Plugin hooks/session lifecycle: include
sessionKeyinsession_start/session_endhook events and contexts so plugins can correlate lifecycle callbacks with routing identity. (#26394) Thanks @tempeste. - Hooks/message lifecycle: add internal hook events
message:transcribedandmessage:preprocessed, plus richer outboundmessage:sentcontext (isGroup,groupId) for group-conversation correlation and post-transcription automations. (#9859) Thanks @Drickon. - Media understanding/audio echo: add optional
tools.media.audio.echoTranscript+echoFormatto send a pre-agent transcript confirmation message to the originating chat, with echo disabled by default. (#32150) Thanks @AytuncYildizli. - Plugin runtime/system: expose
runtime.system.requestHeartbeatNow(...)so extensions can wake targeted sessions immediately after enqueueing system events. (#19464) Thanks @AustinEral. - Plugin runtime/events: expose
runtime.events.onAgentEventandruntime.events.onSessionTranscriptUpdatefor extension-side subscriptions, and isolate transcript-listener failures so one faulty listener cannot break the entire update fanout. (#16044) Thanks @scifantastic. - CLI/Banner taglines: add
cli.banner.taglineMode(random|default|off) to control funny tagline behavior in startup output, with docs + FAQ guidance and regression tests for config override behavior.
Breaking
- BREAKING: Onboarding now defaults
tools.profiletomessagingfor new local installs (interactive + non-interactive). New setups no longer start with broad coding/system tools unless explicitly configured. - BREAKING: ACP dispatch now defaults to enabled unless explicitly disabled (
acp.dispatch.enabled=false). If you need to pause ACP turn routing while keeping/acpcontrols, setacp.dispatch.enabled=false. Docs: https://docs.openclaw.ai/tools/acp-agents - BREAKING: Plugin SDK removed
api.registerHttpHandler(...). Plugins must register explicit HTTP routes viaapi.registerHttpRoute({ path, auth, match, handler }), and dynamic webhook lifecycles should useregisterPluginHttpRoute(...). - BREAKING: Zalo Personal plugin (
@openclaw/zalouser) no longer depends on externalzca-compatible CLI binaries (openzca,zca-cli) for runtime send/listen/login; operators should useopenclaw channels login --channel zalouserafter upgrade to refresh sessions in the new JS-native path.
Fixes
- Plugin command/runtime hardening: validate and normalize plugin command name/description at registration boundaries, and guard Telegram native menu normalization paths so malformed plugin command specs cannot crash startup (
trimon undefined). (#31997) Fixes #31944. Thanks @liuxiaopai-ai. - Telegram: guard duplicate-token checks and gateway startup token normalization when account tokens are missing, preventing
token.trim()crashes during status/start flows. (#31973) Thanks @ningding97. - Discord/lifecycle startup status: push an immediate
connectedstatus snapshot when the gateway is already connected before lifecycle debug listeners attach, with abort-guarding to avoid contradictory status flips during pre-aborted startup. (#32336) Thanks @mitchmcalister. - Feishu/multi-app mention routing: guard mention detection in multi-bot groups by validating mention display name alongside bot
open_id, preventing false-positive self-mentions from Feishu WebSocket remapping so only the actually mentioned bot responds underrequireMention. (#30315) Thanks @teaguexiao. - Feishu/session-memory hook parity: trigger the shared
before_resetsession-memory hook path when Feishu/newand/resetcommands execute so reset flows preserve memory behavior consistent with other channels. (#31437) Thanks @Linux2010. - Feishu/LINE group system prompts: forward per-group
systemPromptconfig into inbound contextGroupSystemPromptfor Feishu and LINE group/room events so configured group-specific behavior actually applies at dispatch time. (#31713) Thanks @whiskyboy. - Mentions/Slack formatting hardening: add null-safe guards for runtime text normalization paths so malformed/undefined text payloads do not crash mention stripping or mrkdwn conversion. (#31865) Thanks @stone-jin.
- Feishu/Plugin sdk compatibility: add safe webhook default fallbacks when loading Feishu monitor state so mixed-version installs no longer crash if older
openclaw/plugin-sdkbuilds omit webhook default constants. (#31606) - Feishu/group broadcast dispatch: add configurable multi-agent group broadcast dispatch with observer-session isolation, cross-account dedupe safeguards, and non-mention history buffering rules that avoid duplicate replay in broadcast/topic workflows. (#29575) Thanks @ohmyskyhigh.
- Gateway/Subagent TLS pairing: allow authenticated local
gateway-clientbackend self-connections to skip device pairing while still requiring pairing for non-local/direct-host paths, restoringsessions_spawnwithgateway.tls.enabled=truein Docker/LAN setups. Fixes #30740. Thanks @Sid-Qin and @vincentkoc. - Browser/CDP startup diagnostics: include Chrome stderr output and a Linux no-sandbox hint in startup timeout errors so failed launches are easier to diagnose. (#29312) Thanks @veast.
- Synology Chat/webhook ingress hardening: enforce bounded body reads (size + timeout) via shared request-body guards to prevent unauthenticated slow-body hangs before token validation. (#25831) Thanks @bmendonca3.
- Feishu/Dedup restart resilience: warm persistent dedup state into memory on monitor startup so retry events after gateway restart stay suppressed without requiring initial on-disk probe misses. (#31605)
- Voice-call/runtime lifecycle: prevent
EADDRINUSEloops by resetting failed runtime promises, making webhookstart()idempotent with the actual bound port, and fully cleaning up webhook/tunnel/tailscale resources after startup failures. (#32395) Thanks @scoootscooob. - Gateway/Security hardening: tie loopback-origin dev allowance to actual local socket clients (not Host header claims), add explicit warnings/metrics when
gateway.controlUi.dangerouslyAllowHostHeaderOriginFallbackaccepts websocket origins, harden safe-regex detection for quantified ambiguous alternation patterns (for example(a|aa)+), and bound large regex-evaluation inputs for session-filter and log-redaction paths. - Gateway/Plugin HTTP hardening: require explicit
authfor plugin route registration...
openclaw 2026.3.2-beta.1
Immutable
release. Only release title and notes can be modified.
Changes
- Secrets/SecretRef coverage: expand SecretRef support across the full supported user-supplied credential surface (64 targets total), including runtime collectors,
openclaw secretsplanning/apply/audit flows, onboarding SecretInput UX, and related docs; unresolved refs now fail fast on active surfaces while inactive surfaces report non-blocking diagnostics. (#29580) Thanks @joshavant. - Tools/PDF analysis: add a first-class
pdftool with native Anthropic and Google PDF provider support, extraction fallback for non-native models, configurable defaults (agents.defaults.pdfModel,pdfMaxBytesMb,pdfMaxPages), and docs/tests covering routing, validation, and registration. (#31319) Thanks @tyler6204. - Outbound adapters/plugins: add shared
sendPayloadsupport across direct-text-media, Discord, Slack, WhatsApp, Zalo, and Zalouser with multi-media iteration and chunk-aware text fallback. (#30144) Thanks @nohat. - Models/MiniMax: add first-class
MiniMax-M2.5-highspeedsupport across built-in provider catalogs, onboarding flows, and MiniMax OAuth plugin defaults, while keeping legacyMiniMax-M2.5-Lightningcompatibility for existing configs. - Sessions/Attachments: add inline file attachment support for
sessions_spawn(subagent runtime only) with base64/utf8 encoding, transcript content redaction, lifecycle cleanup, and configurable limits viatools.sessions_spawn.attachments. (#16761) Thanks @napetrov. - Telegram/Streaming defaults: default
channels.telegram.streamingtopartial(fromoff) so new Telegram setups get live preview streaming out of the box, with runtime fallback to message-edit preview when native drafts are unavailable. - Telegram/DM streaming: use
sendMessageDraftfor private preview streaming, keep reasoning/answer preview lanes separated in DM reasoning-stream mode. (#31824) Thanks @obviyus. - Telegram/voice mention gating: add optional
disableAudioPreflighton group/topic config to skip mention-detection preflight transcription for inbound voice notes where operators want text-only mention checks. (#23067) Thanks @yangnim21029. - CLI/Config validation: add
openclaw config validate(with--json) to validate config files before gateway startup, and include detailed invalid-key paths in startup invalid-config errors. (#31220) thanks @Sid-Qin. - Tools/Diffs: add PDF file output support and rendering quality customization controls (
fileQuality,fileScale,fileMaxWidth) for generated diff artifacts, and document PDF as the preferred option when messaging channels compress images. (#31342) Thanks @gumadeiras. - Memory/Ollama embeddings: add
memorySearch.provider = "ollama"andmemorySearch.fallback = "ollama"support, honormodels.providers.ollamasettings for memory embedding requests, and document Ollama embedding usage. (#26349) Thanks @nico-hoff. - Zalo Personal plugin (
@openclaw/zalouser): rebuilt channel runtime to use nativezca-jsintegration in-process, removing external CLI transport usage and keeping QR/login + send/listen flows fully inside OpenClaw. - Plugin SDK/channel extensibility: expose
channelRuntimeonChannelGatewayContextso external channel plugins can access shared runtime helpers (reply/routing/session/text/media/commands) without internal imports. (#25462) Thanks @guxiaobo. - Plugin runtime/STT: add
api.runtime.stt.transcribeAudioFile(...)so extensions can transcribe local audio files through OpenClaw's configured media-understanding audio providers. (#22402) Thanks @benthecarman. - Plugin hooks/session lifecycle: include
sessionKeyinsession_start/session_endhook events and contexts so plugins can correlate lifecycle callbacks with routing identity. (#26394) Thanks @tempeste. - Hooks/message lifecycle: add internal hook events
message:transcribedandmessage:preprocessed, plus richer outboundmessage:sentcontext (isGroup,groupId) for group-conversation correlation and post-transcription automations. (#9859) Thanks @Drickon. - Media understanding/audio echo: add optional
tools.media.audio.echoTranscript+echoFormatto send a pre-agent transcript confirmation message to the originating chat, with echo disabled by default. (#32150) Thanks @AytuncYildizli. - Plugin runtime/system: expose
runtime.system.requestHeartbeatNow(...)so extensions can wake targeted sessions immediately after enqueueing system events. (#19464) Thanks @AustinEral. - Plugin runtime/events: expose
runtime.events.onAgentEventandruntime.events.onSessionTranscriptUpdatefor extension-side subscriptions, and isolate transcript-listener failures so one faulty listener cannot break the entire update fanout. (#16044) Thanks @scifantastic. - CLI/Banner taglines: add
cli.banner.taglineMode(random|default|off) to control funny tagline behavior in startup output, with docs + FAQ guidance and regression tests for config override behavior.
Breaking
- BREAKING: Onboarding now defaults
tools.profiletomessagingfor new local installs (interactive + non-interactive). New setups no longer start with broad coding/system tools unless explicitly configured. - BREAKING: ACP dispatch now defaults to enabled unless explicitly disabled (
acp.dispatch.enabled=false). If you need to pause ACP turn routing while keeping/acpcontrols, setacp.dispatch.enabled=false. Docs: https://docs.openclaw.ai/tools/acp-agents - BREAKING: Plugin SDK removed
api.registerHttpHandler(...). Plugins must register explicit HTTP routes viaapi.registerHttpRoute({ path, auth, match, handler }), and dynamic webhook lifecycles should useregisterPluginHttpRoute(...). - BREAKING: Zalo Personal plugin (
@openclaw/zalouser) no longer depends on externalzca-compatible CLI binaries (openzca,zca-cli) for runtime send/listen/login; operators should useopenclaw channels login --channel zalouserafter upgrade to refresh sessions in the new JS-native path.
Fixes
- Plugin command/runtime hardening: validate and normalize plugin command name/description at registration boundaries, and guard Telegram native menu normalization paths so malformed plugin command specs cannot crash startup (
trimon undefined). (#31997) Fixes #31944. Thanks @liuxiaopai-ai. - Telegram: guard duplicate-token checks and gateway startup token normalization when account tokens are missing, preventing
token.trim()crashes during status/start flows. (#31973) Thanks @ningding97. - Discord/lifecycle startup status: push an immediate
connectedstatus snapshot when the gateway is already connected before lifecycle debug listeners attach, with abort-guarding to avoid contradictory status flips during pre-aborted startup. (#32336) Thanks @mitchmcalister. - Feishu/LINE group system prompts: forward per-group
systemPromptconfig into inbound contextGroupSystemPromptfor Feishu and LINE group/room events so configured group-specific behavior actually applies at dispatch time. (#31713) Thanks @whiskyboy. - Mentions/Slack formatting hardening: add null-safe guards for runtime text normalization paths so malformed/undefined text payloads do not crash mention stripping or mrkdwn conversion. (#31865) Thanks @stone-jin.
- Feishu/Plugin sdk compatibility: add safe webhook default fallbacks when loading Feishu monitor state so mixed-version installs no longer crash if older
openclaw/plugin-sdkbuilds omit webhook default constants. (#31606) - Feishu/group broadcast dispatch: add configurable multi-agent group broadcast dispatch with observer-session isolation, cross-account dedupe safeguards, and non-mention history buffering rules that avoid duplicate replay in broadcast/topic workflows. (#29575) Thanks @ohmyskyhigh.
- Gateway/Subagent TLS pairing: allow authenticated local
gateway-clientbackend self-connections to skip device pairing while still requiring pairing for non-local/direct-host paths, restoringsessions_spawnwithgateway.tls.enabled=truein Docker/LAN setups. Fixes #30740. Thanks @Sid-Qin and @vincentkoc. - Browser/CDP startup diagnostics: include Chrome stderr output and a Linux no-sandbox hint in startup timeout errors so failed launches are easier to diagnose. (#29312) Thanks @veast.
- Synology Chat/webhook ingress hardening: enforce bounded body reads (size + timeout) via shared request-body guards to prevent unauthenticated slow-body hangs before token validation. (#25831) Thanks @bmendonca3.
- Feishu/Dedup restart resilience: warm persistent dedup state into memory on monitor startup so retry events after gateway restart stay suppressed without requiring initial on-disk probe misses. (#31605)
- Voice-call/runtime lifecycle: prevent
EADDRINUSEloops by resetting failed runtime promises, making webhookstart()idempotent with the actual bound port, and fully cleaning up webhook/tunnel/tailscale resources after startup failures. (#32395) Thanks @scoootscooob. - Gateway/Security hardening: tie loopback-origin dev allowance to actual local socket clients (not Host header claims), add explicit warnings/metrics when
gateway.controlUi.dangerouslyAllowHostHeaderOriginFallbackaccepts websocket origins, harden safe-regex detection for quantified ambiguous alternation patterns (for example(a|aa)+), and bound large regex-evaluation inputs for session-filter and log-redaction paths. - Gateway/Plugin HTTP hardening: require explicit
authfor plugin route registration, add route ownership guards for duplicatepath+matchregistrations, centralize plugin path matching/auth logic into dedicated modules, and share webhook target-route lifecycle wiring across channel monitors to avoid stale or conflicting registrations. Thanks @tdjackey for reporting. - Browser/Profile defaults: prefer
openclawprofile overchromein headless/no-sandbox environments unless an explicitdefaultProfileis configured. (#14944) Thanks @BenediktSchackenberg. - Gateway/WS security: keep plaintext
ws://loopback-only by default, w...
openclaw 2026.3.1
Immutable
release. Only release title and notes can be modified.
Changes
- Agents/Thinking defaults: set
adaptiveas the default thinking level for Anthropic Claude 4.6 models (including Bedrock Claude 4.6 refs) while keeping other reasoning-capable models atlowunless explicitly configured. - Gateway/Container probes: add built-in HTTP liveness/readiness endpoints (
/health,/healthz,/ready,/readyz) for Docker/Kubernetes health checks, with fallback routing so existing handlers on those paths are not shadowed. (#31272) Thanks @vincentkoc. - Android/Nodes: add
camera.list,device.permissions,device.health, andnotifications.actions(open/dismiss/reply) on Android nodes, plus first-class node-tool actions for the new device/notification commands. (#28260) Thanks @obviyus. - Discord/Thread bindings: replace fixed TTL lifecycle with inactivity (
idleHours, default 24h) plus optional hardmaxAgeHourslifecycle controls, and add/session idle+/session max-agecommands for focused thread-bound sessions. (#27845) Thanks @osolmaz. - Telegram/DM topics: add per-DM
direct+ topic config (allowlists,dmPolicy,skills,systemPrompt,requireTopic), route DM topics as distinct inbound/outbound sessions, and enforce topic-aware authorization/debounce for messages, callbacks, commands, and reactions. Landed from contributor PR #30579 by @kesor. Thanks @kesor. - Web UI/Cron i18n: localize cron page labels, filters, form help text, and validation/error messaging in English and zh-CN. (#29315) Thanks @BUGKillerKing.
- OpenAI/Streaming transport: make
openaiResponses WebSocket-first by default (transport: "auto"with SSE fallback), add shared OpenAI WS stream/connection runtime wiring with per-session cleanup, and preserve server-side compaction payload mutation (store+context_management) on the WS path. - Android/Gateway capability refresh: add live Android capability integration coverage and node canvas capability refresh wiring, plus runtime hardening for A2UI readiness retries, scoped canvas URL normalization, debug diagnostics JSON, and JavaScript MIME delivery. (#28388) Thanks @obviyus.
- Android/Nodes parity: add
system.notify,photos.latest,contacts.search/contacts.add,calendar.events/calendar.add, andmotion.activity/motion.pedometer, with motion sensor-aware command gating and improved activity sampling reliability. (#29398) Thanks @obviyus. - CLI/Config: add
openclaw config fileto print the active config file path resolved fromOPENCLAW_CONFIG_PATHor the default location. (#26256) thanks @cyb1278588254. - Feishu/Docx tables + uploads: add
feishu_docactions for Docx table creation/cell writing (create_table,write_table_cells,create_table_with_values) and image/file uploads (upload_image,upload_file) with stricter create/upload error handling for missingdocument_idand placeholder cleanup failures. (#20304) Thanks @xuhao1. - Feishu/Reactions: add inbound
im.message.reaction.created_v1handling, route verified reactions through synthetic inbound turns, and harden verification with timeout + fail-closed filtering so non-bot or unverified reactions are dropped. (#16716) Thanks @schumilin. - Feishu/Chat tooling: add
feishu_chattool actions for chat info and member queries, with configurable enablement underchannels.feishu.tools.chat. (#14674) Thanks @liuweifly. - Feishu/Doc permissions: support optional owner permission grant fields on
feishu_doccreate and report permission metadata only when the grant call succeeds, with regression coverage for success/failure/omitted-owner paths. (#28295) Thanks @zhoulongchao77. - Web UI/i18n: add German (
de) locale support and auto-render language options from supported locale constants in Overview settings. (#28495) thanks @dsantoreis. - Tools/Diffs: add a new optional
diffsplugin tool for read-only diff rendering from before/after text or unified patches, with gateway viewer URLs for canvas and PNG image output. Thanks @gumadeiras. - Memory/LanceDB: support custom OpenAI
baseUrland embedding dimensions for LanceDB memory. (#17874) Thanks @rish2jain and @vincentkoc. - ACP/ACPX streaming: pin ACPX plugin support to
0.1.15, add configurable ACPX command/version probing, and streamline ACP stream delivery (final_onlydefault + reduced tool-event noise) with matching runtime and test updates. (#30036) Thanks @osolmaz. - Shell env markers: set
OPENCLAW_SHELLacross shell-like runtimes (exec,acp,acp-client,tui-local) so shell startup/config rules can target OpenClaw contexts consistently, and document the markers in env/exec/acp/TUI docs. Thanks @vincentkoc. - Cron/Heartbeat light bootstrap context: add opt-in lightweight bootstrap mode for automation runs (
--light-contextfor cron agent turns andagents.*.heartbeat.lightContextfor heartbeat), keeping onlyHEARTBEAT.mdfor heartbeat runs and skipping bootstrap-file injection for cron lightweight runs. (#26064) Thanks @jose-velez. - OpenAI/WebSocket warm-up: add optional OpenAI Responses WebSocket warm-up (
response.createwithgenerate:false), enable it by default foropenai/*, and exposeparams.openaiWsWarmupfor per-model enable/disable control. - Agents/Subagents runtime events: replace ad-hoc subagent completion system-message handoff with typed internal completion events (
task_completion) that are rendered consistently across direct and queued announce paths, with gateway/CLI plumbing for structuredinternalEvents.
Fixes
- Android/Nodes reliability: reject
facing=bothwhendeviceIdis set to avoid mislabeled duplicate captures, allow notificationopen/replyon non-clearable entries while still gating dismiss, trigger listener rebind before notification actions, and scale invoke-result ack timeout to invoke budget for large clip payloads. (#28260) Thanks @obviyus. - Windows/Plugin install: avoid
spawn EINVALon Windows npm/npx invocations by resolving tonode+ npm CLI scripts instead of spawning.cmddirectly. Landed from contributor PR #31147 by @codertony. Thanks @codertony. - LINE/Voice transcription: classify M4A voice media as
audio/mp4(notvideo/mp4) by checking the MPEG-4ftypmajor brand (M4A/M4B), restoring voice transcription for LINE voice messages. Landed from contributor PR #31151 by @scoootscooob. Thanks @scoootscooob. - Slack/Announce target account routing: enable session-backed announce-target lookup for Slack so multi-account announces resolve the correct
accountIdinstead of defaulting to bot-token context. Landed from contributor PR #31028 by @taw0002. Thanks @taw0002. - Android/Voice screen TTS: stream assistant speech via ElevenLabs WebSocket in Talk Mode, stop cleanly on speaker mute/barge-in, and ignore stale out-of-order stream events. (#29521) Thanks @gregmousseau.
- Android/Photos permissions: declare Android 14+ selected-photo access permission (
READ_MEDIA_VISUAL_USER_SELECTED) and align Android permission/settings paths with current minSdk behavior for more reliable permission state handling. - Web UI/Cron: include configured agent model defaults/fallbacks in cron model suggestions so scheduled-job model autocomplete reflects configured models. (#29709) Thanks @Sid-Qin.
- Cron/Delivery: disable the agent messaging tool when
delivery.modeis"none"so cron output is not sent to Telegram or other channels. (#21808) Thanks @lailoo. - CLI/Cron: clarify
cron listoutput by renamingAgenttoAgent IDand adding aModelcolumn for isolated agent-turn jobs. (#26259) Thanks @openperf. - Feishu/Reply media attachments: send Feishu reply
mediaUrl/mediaUrlspayloads as attachments alongside text/streamed replies in the reply dispatcher, including legacy fallback whenmediaUrlsis empty. (#28959) Thanks @icesword0760. - Slack/User-token resolution: normalize Slack account user-token sourcing through resolved account metadata (
SLACK_USER_TOKENenv + config) so monitor reads, Slack actions, directory lookups, onboarding allow-from resolution, and capabilities probing consistently use the effective user token. (#28103) Thanks @Glucksberg. - Feishu/Outbound session routing: stop assuming bare
oc_identifiers are always group chats, honor explicitdm:/group:prefixes foroc_chat IDs, and default ambiguous bareoc_targets to direct routing to avoid DM session misclassification. (#10407) Thanks @Bermudarat. - Feishu/Group session routing: add configurable group session scopes (
group,group_sender,group_topic,group_topic_sender) with legacytopicSessionMode=enabledcompatibility so Feishu group conversations can isolate sessions by sender/topic as configured. (#17798) Thanks @yfge. - Feishu/Reply-in-thread routing: add
replyInThreadconfig (disabled|enabled) for group replies, propagatereply_in_threadacross text/card/media/streaming sends, and align topic-scoped session routing so newly created reply threads stay on the same session root. (#27325) Thanks @kcinzgg. - Feishu/Probe status caching: cache successful
probeFeishu()bot-info results for 10 minutes (bounded cache with per-account keying) to reduce repeated status/onboarding probe API calls, while bypassing cache for failures and exceptions. (#28907) Thanks @Glucksberg. - Feishu/Opus media send type: send
.opusattachments withmsg_type: "audio"(instead of"media") so Feishu voice messages deliver correctly while.mp4remainsmsg_type: "media"and documents remainmsg_type: "file". (#28269) Thanks @Glucksberg. - Feishu/Mobile video media type: treat inbound
message_type: "media"as video-equivalent for media key extraction, placeholder inference, and media download resolution so mobile-app video sends ingest correctly. (#25502) Thanks @4ier. - Feishu/Inbound sender fallback: fall back to
sender_id.user_idwhensender_id.open_idis missing on inbound events, and use ID-type-aware sender lookup so mobile-delivered messages keep stable sender identity/routing. (#26703)...
openclaw 2026.2.26
Immutable
release. Only release title and notes can be modified.
Changes
- Highlight: External Secrets Management introduces a full
openclaw secretsworkflow (audit,configure,apply,reload) with runtime snapshot activation, strictsecrets applytarget-path validation, safer migration scrubbing, ref-only auth-profile support, and dedicated docs. (#26155) Thanks @joshavant. - ACP/Thread-bound agents: make ACP agents first-class runtimes for thread sessions with
acpspawn/send dispatch integration, acpx backend bridging, lifecycle controls, startup reconciliation, runtime cleanup, and coalesced thread replies. (#23580) thanks @osolmaz. - Agents/Routing CLI: add
openclaw agents bindings,openclaw agents bind, andopenclaw agents unbindfor account-scoped route management, including channel-only to account-scoped binding upgrades, role-aware binding identity handling, plugin-resolved binding account IDs, and optional account-binding prompts inopenclaw channels add. (#27195) thanks @gumadeiras. - Codex/WebSocket transport: make
openai-codexWebSocket-first by default (transport: "auto"with SSE fallback), keep explicit per-model/runtime transport overrides, and add regression coverage + docs for transport selection. - Onboarding/Plugins: let channel plugins own interactive onboarding flows with optional
configureInteractiveandconfigureWhenConfiguredhooks while preserving the generic fallback path. (#27191) thanks @gumadeiras. - Auth/Onboarding: add an explicit account-risk warning and confirmation gate before starting Gemini CLI OAuth, and document the caution in provider docs and the Gemini CLI auth plugin README. (#16683) Thanks @vincentkoc.
- Android/Nodes: add Android
devicecapability plusdevice.statusanddevice.infonode commands, including runtime handler wiring and protocol/registry coverage for device status/info payloads. (#27664) Thanks @obviyus. - Android/Nodes: add
notifications.listsupport on Android nodes and exposenodes notifications_listin agent tooling for listing active device notifications. (#27344) thanks @obviyus. - Docs/Contributing: add Nimrod Gutman to the maintainer roster in
CONTRIBUTING.md. (#27840) Thanks @ngutman.
Fixes
- Telegram/DM allowlist runtime inheritance: enforce
dmPolicy: "allowlist"allowFromrequirements using effective account-plus-parent config across account-capable channels (Telegram, Discord, Slack, Signal, iMessage, IRC, BlueBubbles, WhatsApp), and alignopenclaw doctorchecks to the same inheritance logic so DM traffic is not silently dropped after upgrades. (#27936) Thanks @widingmarcus-cyber. - Delivery queue/recovery backoff: prevent retry starvation by persisting
lastAttemptAton failed sends and deferring recovery retries until each entry'slastAttemptAt + backoffwindow is eligible, while continuing to recover ready entries behind deferred ones. Landed from contributor PR #27710 by @Jimmy-xuzimo. Thanks @Jimmy-xuzimo. - Gemini OAuth/Auth flow: align OAuth project discovery metadata and endpoint fallback handling for Gemini CLI auth, including fallback coverage for environment-provided project IDs. (#16684) Thanks @vincentkoc.
- Google Chat/Lifecycle: keep Google Chat
startAccountpending until abort in webhook mode so startup is no longer interpreted as immediate exit, preventing auto-restart loops and webhook-target churn. (#27384) thanks @junsuwhy. - Temp dirs/Linux umask: force
0700permissions after temp-dir creation and self-heal existing writable temp dirs before trust checks soumask 0002installs no longer crash-loop on startup. Landed from contributor PR #27860 by @stakeswky. (#27853) Thanks @stakeswky. - Nextcloud Talk/Lifecycle: keep
startAccountpending until abort and stop the webhook monitor on shutdown, preventingEADDRINUSErestart loops when the gateway manages account lifecycle. (#27897) - Microsoft Teams/File uploads: acknowledge
fileConsent/invokeimmediately (invokeResponsebefore upload + file card send) so Teams no longer shows false "Something went wrong" timeout banners while upload completion continues asynchronously; includes updated async regression coverage. Landed from contributor PR #27641 by @scz2011. - Queue/Drain/Cron reliability: harden lane draining with guaranteed
drainingflag reset on synchronous pump failures, reject new queue enqueues during gateway restart drain windows (instead of silently killing accepted tasks), add/stopqueued-backlog cutoff metadata with stale-message skipping (while avoiding cross-session native-stop cutoff bleed), and raise isolated cronagentTurnouter safety timeout to avoid false 10-minute timeout races against longer agent session timeouts. (#27407, #27332, #27427) - Typing/Main reply pipeline: always mark dispatch idle in
agent-runnerfinalization so typing cleanup runs even when dispatcheronIdledoes not fire, preventing stuck typing indicators after run completion. (#27250) Thanks @Sid-Qin. - Typing/TTL safety net: add max-duration guardrails to shared typing callbacks so stuck lifecycle edges auto-stop typing indicators even when explicit idle/cleanup signals are missed. (#27428) Thanks @Crpdim.
- Typing/Cross-channel leakage: unify run-scoped typing suppression for cross-channel/internal-webchat routes, preserve current inbound origin as embedded run message channel context, harden shared typing keepalive with consecutive-failure circuit breaker edge-case handling, and enforce dispatcher completion/idle waits in extension dispatcher callsites (Feishu, Matrix, Mattermost, MSTeams) so typing indicators always clean up on success/error paths. Related: #27647, #27493, #27598. Supersedes/replaces draft PRs: #27640, #27593, #27540.
- Telegram/sendChatAction 401 handling: add bounded exponential backoff + temporary local typing suppression after repeated unauthorized failures to stop unbounded
sendChatActionretry loops that can trigger Telegram abuse enforcement and bot deletion. (#27415) Thanks @widingmarcus-cyber. - Telegram/Webhook startup: clarify webhook config guidance, allow
channels.telegram.webhookPort: 0for ephemeral listener binding, and log both the local listener URL and Telegram-advertised webhook URL with the bound port. (#25732) thanks @huntharo. - Config/Doctor allowlist safety: reject
dmPolicy: "allowlist"configs with emptyallowFrom, add Telegram account-level inheritance-aware validation, and teachopenclaw doctor --fixto restore missingallowFromentries from pairing-store files when present, preventing silent DM drops after upgrades. (#27936) Thanks @widingmarcus-cyber. - Browser/Chrome extension handshake: bind relay WS message handling before
onopenand add non-blockingconnect.challengeresponse handling for gateway-style handshake frames, avoiding stuck…badge states when challenge frames arrive immediately on connect. Landed from contributor PR #22571 by @pandego. (#22553) - Browser/Extension relay init: dedupe concurrent same-port relay startup with shared in-flight initialization promises so callers await one startup lifecycle and receive consistent success/failure results. Landed from contributor PR #21277 by @HOYALIM. (Related #20688)
- Browser/Fill relay + CLI parity: accept
act.fillfields without explicittypeby defaulting missing/emptytypetotextin both browser relay route parsing andopenclaw browser fillCLI field parsing, so relay calls no longer fail when the model omits field type metadata. Landed from contributor PR #27662 by @Uface11. (#27296) Thanks @Uface11. - Feishu/Permission error dispatch: merge sender-name permission notices into the main inbound dispatch so one user message produces one agent turn/reply (instead of a duplicate permission-notice turn), with regression coverage. (#27381) thanks @byungsker.
- Agents/Canvas default node resolution: when multiple connected canvas-capable nodes exist and no single
mac-*candidate is selected, default to the first connected candidate instead of failing withnode requiredfor implicit-node canvas tool calls. Landed from contributor PR #27444 by @carbaj03. Thanks @carbaj03. - TUI/stream assembly: preserve streamed text across real tool-boundary drops without keeping stale streamed text when non-text blocks appear only in the final payload. Landed from contributor PR #27711 by @scz2011. (#27674)
- Hooks/Internal
message:sent: forwardsessionKeyon outbound sends from agent delivery, cron isolated delivery, gateway receipt acks, heartbeat sends, session-maintenance warnings, and restart-sentinel recovery so internalmessage:senthooks consistently dispatch with session context, includingopenclaw agent --deliverruns resumed via--session-id(without explicit--session-key). Landed from contributor PR #27584 by @qualiobra. Thanks @qualiobra. - Pi image-token usage: stop re-injecting history image blocks each turn, process image references from the current prompt only, and prune already-answered user-image blocks in stored history to prevent runaway token growth. (#27602)
- BlueBubbles/SSRF: auto-allowlist the configured
serverUrlhostname for attachment fetches so localhost/private-IP BlueBubbles setups are no longer false-blocked by default SSRF checks. Landed from contributor PR #27648 by @lailoo. (#27599) Thanks @taylorhou for reporting. - Agents/Compaction + onboarding safety: prevent destructive double-compaction by stripping stale assistant usage around compaction boundaries, skipping post-compaction custom metadata writes in the same attempt, and cancelling safeguard compaction when there are no real conversation messages to summarize; harden workspace/bootstrap detection for memory-backed workspaces; and change
openclaw onboard --resetdefault scope toconfig+creds+sessions(workspace deletion now requires--reset-scope full). (#26458, #27314) Thanks @jaden-clovervnd, @Sid-Qin, and @widingmarcus-cyber for fix direction in #26502, #26529, and #27492. - NO_REPLY suppression: suppress
NO_REPLYbefore ...
openclaw 2026.2.25
Immutable
release. Only release title and notes can be modified.
Changes
- Android/Chat: improve streaming delivery handling and markdown rendering quality in the native Android chat UI, including better GitHub-flavored markdown behavior. (#26079) Thanks @obviyus.
- Android/Startup perf: defer foreground-service startup, move WebView debugging init out of critical startup, and add startup macrobenchmark + low-noise perf CLI scripts for deterministic cold-start tracking. (#26659) Thanks @obviyus.
- UI/Chat compose: add mobile stacked layout for compose action buttons on small screens to improve send/session controls usability. (#11167) Thanks @junyiz.
- Heartbeat/Config: replace heartbeat DM toggle with
agents.defaults.heartbeat.directPolicy(allow|block; also supported per-agent viaagents.list[].heartbeat.directPolicy) for clearer delivery semantics. - Onboarding/Security: clarify onboarding security notices that OpenClaw is personal-by-default (single trusted operator boundary) and shared/multi-user setups require explicit lock-down/hardening.
- Branding/Docs + Apple surfaces: replace remaining
bot.moltlaunchd label, bundle-id, logging subsystem, and command examples withai.openclawacross docs, iOS app surfaces, helper scripts, and CLI test fixtures. - Agents/Config: remind agents to call
config.schemabefore config edits or config-field questions to avoid guessing. Thanks @thewilloftheshadow. - Dependencies: update workspace dependency pins and lockfile (Bedrock SDK
3.998.0,@mariozechner/pi-*0.55.1, TypeScript native preview7.0.0-dev.20260225.1) while keeping@buape/carbonpinned.
Breaking
- BREAKING: Heartbeat direct/DM delivery default is now
allowagain. To keep DM-blocked behavior from2026.2.24, setagents.defaults.heartbeat.directPolicy: "block"(or per-agent override).
Fixes
- Agents/Subagents delivery: refactor subagent completion announce dispatch into an explicit queue/direct/fallback state machine, recover outbound channel-plugin resolution in cold/stale plugin-registry states across announce/message/gateway send paths, finalize cleanup bookkeeping when announce flow rejects, and treat Telegram sends without
message_idas delivery failures (instead of false-success"unknown"IDs). (#26867, #25961, #26803, #25069, #26741) Thanks @SmithLabsLLC and @docaohieu2808. - Telegram/Webhook: pre-initialize webhook bots, switch webhook processing to callback-mode JSON handling, and preserve full near-limit payload reads under delayed handlers to prevent webhook request hangs and dropped updates. (#26156)
- Slack/Session threads: prevent oversized parent-session inheritance from silently bricking new thread sessions, surface embedded context-overflow empty-result failures to users, and add configurable
session.parentForkMaxTokens(default100000,0disables). (#26912) Thanks @markshields-tl. - Cron/Message multi-account routing: honor explicit
delivery.accountIdfor isolated cron delivery resolution, and whenmessage.sendomitsaccountId, fall back to the sending agent's bound channel account instead of defaulting to the global account. (#27015, #26975) Thanks @lbo728 and @stakeswky. - Gateway/Message media roots: thread
agentIdthrough gatewaysendRPC and prefer explicitagentIdover session/default resolution so non-default agent workspace media sends no longer fail withLocalMediaAccessError; added regression coverage for agent precedence and blank-agent fallback. (#23249) Thanks @Sid-Qin. - Followups/Routing: when explicit origin routing fails, allow same-channel fallback dispatch (while still blocking cross-channel fallback) so followup replies do not get dropped on transient origin-adapter failures. (#26109) Thanks @Sid-Qin.
- Cron/Announce duplicate guard: track attempted announce/direct delivery separately from confirmed
delivered, and suppress fallback main-session cron summaries when delivery was already attempted to avoid duplicate end-user sends in uncertain-ack paths. (#27018) - LINE/Lifecycle: keep LINE
startAccountpending until abort so webhook startup is no longer misread as immediate channel exit, preventing restart-loop storms on LINE provider boot. (#26528) Thanks @Sid-Qin. - Discord/Gateway: capture and drain startup-time gateway
errorevents before lifecycle listeners attach so earlyFatal Gateway error: 4014closes surface as actionable intent guidance instead of uncaught gateway crashes. (#23832) Thanks @theotarr. - Discord/Inbound text: preserve embed
title+descriptionfallback text in message and forwarded snapshot parsing so embed titles are not silently dropped from agent input. (#26946) Thanks @stakeswky. - Slack/Inbound media fallback: deliver file-only messages even when Slack media downloads fail by adding a filename placeholder fallback, capping fallback names to the shared media-file limit, and normalizing empty filenames to
fileso attachment-only messages are not silently dropped. (#25181) Thanks @justinhuangcode. - Telegram/Preview cleanup: keep finalized text previews when a later assistant message is media-only (for example mixed text plus voice turns) by skipping finalized preview archival at assistant-message boundaries, preventing cleanup from deleting already-visible final text messages. (#27042)
- Telegram/Markdown spoilers: keep valid
||spoiler||pairs while leaving unmatched trailing||delimiters as literal text, avoiding false all-or-nothing spoiler suppression. (#26105) Thanks @Sid-Qin. - Slack/Allowlist channels: match channel IDs case-insensitively during channel allowlist resolution so lowercase config keys (for example
c0abc12345) correctly match Slack runtime IDs (C0ABC12345) undergroupPolicy: "allowlist", preventing silent channel-event drops. (#26878) Thanks @lbo728. - Discord/Typing indicator: prevent stuck typing indicators by sealing channel typing keepalive callbacks after idle/cleanup and ensuring Discord dispatch always marks typing idle even if preview-stream cleanup fails. (#26295) Thanks @ngutman.
- Channels/Typing indicator: guard typing keepalive start callbacks after idle/cleanup close so post-close ticks cannot re-trigger stale typing indicators. (#26325) Thanks @win4r.
- Followups/Typing indicator: ensure followup turns mark dispatch idle on every exit path (including
NO_REPLY, empty payloads, and agent errors) so typing keepalive cleanup always runs and channel typing indicators do not get stuck after queued/silent followups. (#26881) Thanks @codexGW. - Voice-call/TTS tools: hide the
ttstool when the message provider isvoice, preventing voice-call runs from selecting self-playback TTS and falling into silent no-output loops. (#27025) - Agents/Tools: normalize non-standard plugin tool results that omit
contentso embedded runs no longer crash withCannot read properties of undefined (reading 'filter')after tool completion (includingtesseramemo_query). (#27007) - Cron/Model overrides: when isolated
payload.modelis no longer allowlisted, fall back to default model selection instead of failing the job, while still returning explicit errors for invalid model strings. (#26717) Thanks @Youyou972. - Agents/Model fallback: keep explicit text + image fallback chains reachable even when
agents.defaults.modelsallowlists are present, prefer explicit runagentIdover session-key parsing for followup fallback override resolution (with session-key fallback), treat agent-level fallback overrides as configured in embedded runner preflight, and classifymodel_cooldown/cooling downerrors asrate_limitso failover continues. (#11972, #24137, #17231) - Agents/Model fallback: keep same-provider fallback chains active when session model differs from configured primary, infer cooldown reason from provider profile state (instead of
disabledReasononly), keep no-profile fallback providers eligible (env/models.json paths), and only relax same-provider cooldown fallback attempts forrate_limit. (#23816) thanks @ramezgaberiel. - Agents/Model fallback: continue fallback traversal on unrecognized errors when candidates remain, while still throwing the original unknown error on the last candidate. (#26106) Thanks @Sid-Qin.
- Models/Auth probes: map permanent auth failover reasons (
auth_permanent, for example revoked keys) into probe auth status instead ofunknown, soopenclaw models status --probereports actionable auth failures. (#25754) thanks @rrenamed. - Hooks/Inbound metadata: include
guildIdandchannelNameinmessage_receivedmetadata for both plugin and internal hook paths. (#26115) Thanks @davidrudduck. - Discord/Component auth: evaluate guild component interactions with command-gating authorizers so unauthorized users no longer get
CommandAuthorized: trueon modal/button events. (#26119) Thanks @bmendonca3. - Security/Gateway auth: require pairing for operator device-identity sessions authenticated with shared token auth so unpaired devices cannot self-assign operator scopes. Thanks @tdjackey for reporting.
- Security/Gateway WebSocket auth: enforce origin checks for direct browser WebSocket clients beyond Control UI/Webchat, apply password-auth failure throttling to browser-origin loopback attempts (including localhost), and block silent auto-pairing for non-Control-UI browser clients to prevent cross-origin brute-force and session takeover chains. This ships in the next npm release (
2026.2.25). Thanks @luz-oasis for reporting. - Security/Gateway trusted proxy: require
operatorrole for the Control UI trusted-proxy pairing bypass so unpairednodesessions can no longer connect viaclient.id=control-uiand invoke node event methods. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/macOS beta onboarding: remove Anthropic OAuth sign-in and the legacy
oauth.jsononboarding path that exposed the PKCE verifier via OAuthstate; this impacted the macOS beta onboarding path only. Anthropic subscription auth is now...
openclaw 2026.2.25-beta.1
Immutable
release. Only release title and notes can be modified.
Changes
- Android/Chat: improve streaming delivery handling and markdown rendering quality in the native Android chat UI, including better GitHub-flavored markdown behavior. (#26079) Thanks @obviyus.
- Android/Startup perf: defer foreground-service startup, move WebView debugging init out of critical startup, and add startup macrobenchmark + low-noise perf CLI scripts for deterministic cold-start tracking. (#26659) Thanks @obviyus.
- UI/Chat compose: add mobile stacked layout for compose action buttons on small screens to improve send/session controls usability. (#11167) Thanks @junyiz.
- Heartbeat/Config: replace heartbeat DM toggle with
agents.defaults.heartbeat.directPolicy(allow|block; also supported per-agent viaagents.list[].heartbeat.directPolicy) for clearer delivery semantics. - Onboarding/Security: clarify onboarding security notices that OpenClaw is personal-by-default (single trusted operator boundary) and shared/multi-user setups require explicit lock-down/hardening.
- Branding/Docs + Apple surfaces: replace remaining
bot.moltlaunchd label, bundle-id, logging subsystem, and command examples withai.openclawacross docs, iOS app surfaces, helper scripts, and CLI test fixtures. - Agents/Config: remind agents to call
config.schemabefore config edits or config-field questions to avoid guessing. Thanks @thewilloftheshadow. - Dependencies: update workspace dependency pins and lockfile (Bedrock SDK
3.998.0,@mariozechner/pi-*0.55.1, TypeScript native preview7.0.0-dev.20260225.1) while keeping@buape/carbonpinned.
Fixes
- Agents/Subagents delivery: refactor subagent completion announce dispatch into an explicit queue/direct/fallback state machine, recover outbound channel-plugin resolution in cold/stale plugin-registry states across announce/message/gateway send paths, finalize cleanup bookkeeping when announce flow rejects, and treat Telegram sends without
message_idas delivery failures (instead of false-success"unknown"IDs). (#26867, #25961, #26803, #25069, #26741) Thanks @SmithLabsLLC and @docaohieu2808. - Telegram/Webhook: pre-initialize webhook bots, switch webhook processing to callback-mode JSON handling, and preserve full near-limit payload reads under delayed handlers to prevent webhook request hangs and dropped updates. (#26156)
- Slack/Session threads: prevent oversized parent-session inheritance from silently bricking new thread sessions, surface embedded context-overflow empty-result failures to users, and add configurable
session.parentForkMaxTokens(default100000,0disables). (#26912) Thanks @markshields-tl. - Cron/Message multi-account routing: honor explicit
delivery.accountIdfor isolated cron delivery resolution, and whenmessage.sendomitsaccountId, fall back to the sending agent's bound channel account instead of defaulting to the global account. (#27015, #26975) Thanks @lbo728 and @stakeswky. - Gateway/Message media roots: thread
agentIdthrough gatewaysendRPC and prefer explicitagentIdover session/default resolution so non-default agent workspace media sends no longer fail withLocalMediaAccessError; added regression coverage for agent precedence and blank-agent fallback. (#23249) Thanks @Sid-Qin. - Followups/Routing: when explicit origin routing fails, allow same-channel fallback dispatch (while still blocking cross-channel fallback) so followup replies do not get dropped on transient origin-adapter failures. (#26109) Thanks @Sid-Qin.
- Cron/Announce duplicate guard: track attempted announce/direct delivery separately from confirmed
delivered, and suppress fallback main-session cron summaries when delivery was already attempted to avoid duplicate end-user sends in uncertain-ack paths. (#27018) - LINE/Lifecycle: keep LINE
startAccountpending until abort so webhook startup is no longer misread as immediate channel exit, preventing restart-loop storms on LINE provider boot. (#26528) Thanks @Sid-Qin. - Discord/Gateway: capture and drain startup-time gateway
errorevents before lifecycle listeners attach so earlyFatal Gateway error: 4014closes surface as actionable intent guidance instead of uncaught gateway crashes. (#23832) Thanks @theotarr. - Discord/Inbound text: preserve embed
title+descriptionfallback text in message and forwarded snapshot parsing so embed titles are not silently dropped from agent input. (#26946) Thanks @stakeswky. - Slack/Inbound media fallback: deliver file-only messages even when Slack media downloads fail by adding a filename placeholder fallback, capping fallback names to the shared media-file limit, and normalizing empty filenames to
fileso attachment-only messages are not silently dropped. (#25181) Thanks @justinhuangcode. - Telegram/Preview cleanup: keep finalized text previews when a later assistant message is media-only (for example mixed text plus voice turns) by skipping finalized preview archival at assistant-message boundaries, preventing cleanup from deleting already-visible final text messages. (#27042)
- Telegram/Markdown spoilers: keep valid
||spoiler||pairs while leaving unmatched trailing||delimiters as literal text, avoiding false all-or-nothing spoiler suppression. (#26105) Thanks @Sid-Qin. - Slack/Allowlist channels: match channel IDs case-insensitively during channel allowlist resolution so lowercase config keys (for example
c0abc12345) correctly match Slack runtime IDs (C0ABC12345) undergroupPolicy: "allowlist", preventing silent channel-event drops. (#26878) Thanks @lbo728. - Discord/Typing indicator: prevent stuck typing indicators by sealing channel typing keepalive callbacks after idle/cleanup and ensuring Discord dispatch always marks typing idle even if preview-stream cleanup fails. (#26295) Thanks @ngutman.
- Channels/Typing indicator: guard typing keepalive start callbacks after idle/cleanup close so post-close ticks cannot re-trigger stale typing indicators. (#26325) Thanks @win4r.
- Followups/Typing indicator: ensure followup turns mark dispatch idle on every exit path (including
NO_REPLY, empty payloads, and agent errors) so typing keepalive cleanup always runs and channel typing indicators do not get stuck after queued/silent followups. (#26881) Thanks @codexGW. - Voice-call/TTS tools: hide the
ttstool when the message provider isvoice, preventing voice-call runs from selecting self-playback TTS and falling into silent no-output loops. (#27025) - Agents/Tools: normalize non-standard plugin tool results that omit
contentso embedded runs no longer crash withCannot read properties of undefined (reading 'filter')after tool completion (includingtesseramemo_query). (#27007) - Cron/Model overrides: when isolated
payload.modelis no longer allowlisted, fall back to default model selection instead of failing the job, while still returning explicit errors for invalid model strings. (#26717) Thanks @Youyou972. - Agents/Model fallback: keep explicit text + image fallback chains reachable even when
agents.defaults.modelsallowlists are present, prefer explicit runagentIdover session-key parsing for followup fallback override resolution (with session-key fallback), treat agent-level fallback overrides as configured in embedded runner preflight, and classifymodel_cooldown/cooling downerrors asrate_limitso failover continues. (#11972, #24137, #17231) - Agents/Model fallback: keep same-provider fallback chains active when session model differs from configured primary, infer cooldown reason from provider profile state (instead of
disabledReasononly), keep no-profile fallback providers eligible (env/models.json paths), and only relax same-provider cooldown fallback attempts forrate_limit. (#23816) thanks @ramezgaberiel. - Agents/Model fallback: continue fallback traversal on unrecognized errors when candidates remain, while still throwing the original unknown error on the last candidate. (#26106) Thanks @Sid-Qin.
- Models/Auth probes: map permanent auth failover reasons (
auth_permanent, for example revoked keys) into probe auth status instead ofunknown, soopenclaw models status --probereports actionable auth failures. (#25754) thanks @rrenamed. - Hooks/Inbound metadata: include
guildIdandchannelNameinmessage_receivedmetadata for both plugin and internal hook paths. (#26115) Thanks @davidrudduck. - Discord/Component auth: evaluate guild component interactions with command-gating authorizers so unauthorized users no longer get
CommandAuthorized: trueon modal/button events. (#26119) Thanks @bmendonca3. - Security/Gateway auth: require pairing for operator device-identity sessions authenticated with shared token auth so unpaired devices cannot self-assign operator scopes. Thanks @tdjackey for reporting.
- Security/Gateway WebSocket auth: enforce origin checks for direct browser WebSocket clients beyond Control UI/Webchat, apply password-auth failure throttling to browser-origin loopback attempts (including localhost), and block silent auto-pairing for non-Control-UI browser clients to prevent cross-origin brute-force and session takeover chains. This ships in the next npm release (
2026.2.25). Thanks @luz-oasis for reporting. - Security/Gateway trusted proxy: require
operatorrole for the Control UI trusted-proxy pairing bypass so unpairednodesessions can no longer connect viaclient.id=control-uiand invoke node event methods. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/macOS beta onboarding: remove Anthropic OAuth sign-in and the legacy
oauth.jsononboarding path that exposed the PKCE verifier via OAuthstate; this impacted the macOS beta onboarding path only. Anthropic subscription auth is now setup-token-only and will ship in the next npm release (2026.2.25). Thanks @zdi-disclosures for reporting. - Security/Microsoft Teams file consent: bind
fileConsent/invokeupload acceptance/decline to the origin...
openclaw 2026.2.24
Immutable
release. Only release title and notes can be modified.
Changes
- Auto-reply/Abort shortcuts: expand standalone stop phrases (
stop openclaw,stop action,stop run,stop agent,please stop, and related variants), accept trailing punctuation (for exampleSTOP OPENCLAW!!!), add multilingual stop keywords (including ES/FR/ZH/HI/AR/JP/DE/PT/RU forms), and treat exactdo not do thatas a stop trigger while preserving strict standalone matching. (#25103) Thanks @steipete and @vincentkoc. - Android/App UX: ship a native four-step onboarding flow, move post-onboarding into a five-tab shell (Connect, Chat, Voice, Screen, Settings), add a full Connect setup/manual mode screen, and refresh Android chat/settings surfaces for the new navigation model.
- Talk/Gateway config: add provider-agnostic Talk configuration with legacy compatibility, and expose gateway Talk ElevenLabs config metadata for setup/status surfaces.
- Security/Audit: add
security.trust_model.multi_user_heuristicto flag likely shared-user ingress and clarify the personal-assistant trust model, with hardening guidance for intentional multi-user setups (sandbox.mode="all", workspace-scoped FS, reduced tool surface, no personal/private identities on shared runtimes). - Dependencies: refresh key runtime and tooling packages across the workspace (Bedrock SDK, pi runtime stack, OpenAI, Google auth, and oxlint/oxfmt), while intentionally keeping
@buape/carbonpinned.
Breaking
- BREAKING: Heartbeat delivery now blocks direct/DM targets when destination parsing identifies a direct chat (for example
user:<id>, Telegram user chat IDs, or WhatsApp direct numbers/JIDs). Heartbeat runs still execute, but direct-message delivery is skipped and only non-DM destinations (for example channel/group targets) can receive outbound heartbeat messages. - BREAKING: Security/Sandbox: block Docker
network: "container:<id>"namespace-join mode by default for sandbox and sandbox-browser containers. To keep that behavior intentionally, setagents.defaults.sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true(break-glass). Thanks @tdjackey for reporting.
Fixes
- Routing/Session isolation: harden followup routing so explicit cross-channel origin replies never fall back to the active dispatcher on route failure, preserve queued overflow summary routing metadata (
channel/to/thread) across followup drain, and prefer originating channel context over internal provider tags for embedded followup runs. This prevents webchat/control-ui context from hijacking Discord-targeted replies in shared sessions. (#25864) Thanks @Gamedesigner. - Security/Routing: fail closed for shared-session cross-channel replies by binding outbound target resolution to the current turn’s source channel metadata (instead of stale session route fallbacks), and wire those turn-source fields through gateway + command delivery planners with regression coverage. (#24571) Thanks @brandonwise.
- Heartbeat routing: prevent heartbeat leakage/spam into Discord and other direct-message destinations by blocking direct-chat heartbeat delivery targets and keeping blocked-delivery cron/exec prompts internal-only. (#25871)
- Heartbeat defaults/prompts: switch the implicit heartbeat delivery target from
lasttonone(opt-in for external delivery), and use internal-only cron/exec heartbeat prompt wording when delivery is disabled so background checks do not nudge user-facing relay behavior. (#25871, #24638, #25851) - Auto-reply/Heartbeat queueing: drop heartbeat runs when a session already has an active run instead of enqueueing a stale followup, preventing duplicate heartbeat response branches after queue drain. (#25610, #25606) Thanks @mcaxtr.
- Cron/Heartbeat delivery: stop inheriting cached session
lastThreadIdfor heartbeat-mode target resolution unless a thread/topic is explicitly requested, so announce-mode cron and heartbeat deliveries stay on top-level destinations instead of leaking into active conversation threads. (#25730) Thanks @markshields-tl. - Messaging tool dedupe: treat originating channel metadata as authoritative for same-target
message.sendsuppression in proactive runs (heartbeat/cron/exec-event), including synthetic-provider contexts, sodelivery-mirrortranscript entries no longer cause duplicate Telegram sends. (#25835) Thanks @jadeathena84-arch. - Channels/Typing keepalive: refresh channel typing callbacks on a keepalive interval during long replies and clear keepalive timers on idle/cleanup across core + extension dispatcher callsites so typing indicators do not expire mid-inference. (#25886, #25882) Thanks @stakeswky.
- Agents/Model fallback: when a run is currently on a configured fallback model, keep traversing the configured fallback chain instead of collapsing straight to primary-only, preventing dead-end failures when primary stays in cooldown. (#25922, #25912) Thanks @Taskle.
- Gateway/Models: honor explicit
agents.defaults.modelsallowlist refs even when bundled model catalog data is stale, synthesize missing allowlist entries inmodels.list, and allowsessions.patch//modelselection for those refs without falsemodel not allowederrors. (#20291) Thanks @kensipe, @nikolasdehor, and @vincentkoc. - Control UI/Agents: inherit
agents.defaults.model.fallbacksin the Overview fallback input when no per-agent model entry exists, while preserving explicit per-agent fallback overrides (including empty lists). (#25729, #25710) Thanks @Suko. - Automation/Subagent/Cron reliability: honor
ANNOUNCE_SKIPinsessions_spawncompletion/direct announce flows (no user-visible token leaks), add transient direct-announce retries for channel unavailability (for example WhatsApp listener reconnect windows), and includecronin thecodingtool profile so/tools/invokecan execute cron actions when explicitly allowed by gateway policy. (#25800, #25656, #25842, #25813, #25822, #25821) Thanks @astra-fer, @aaajiao, @dwight11232-coder, @kevinWangSheng, @widingmarcus-cyber, and @stakeswky. - Discord/Voice reliability: restore runtime DAVE dependency (
@snazzah/davey), add configurable DAVE join options (channels.discord.voice.daveEncryptionandchannels.discord.voice.decryptionFailureTolerance), clean up voice listeners/session teardown, guard against stale connection events, and trigger controlled rejoin recovery after repeated decrypt failures to improve inbound STT stability under DAVE receive errors. (#25861, #25372, #24883, #24825, #23890, #23105, #22961, #23421, #23278, #23032) - Discord/Block streaming: restore block-streamed reply delivery by suppressing only reasoning payloads (instead of all
blockpayloads), fixing missing Discord replies inchannels.discord.streaming=blockmode. (#25839, #25836, #25792) Thanks @pewallin. - Discord/Proxy + reactions + model picker: thread channel proxy fetch into inbound media/sticker downloads, use proxy-aware gateway metadata fetch for WSL/corporate proxy setups, wire
messages.statusReactions.{emojis,timing}into Discord reaction lifecycle control, and compact model-pickercustom_idkeys to stay under Discord's 100-char limit while keeping backward-compatible parsing. (#25232, #25507, #25564, #25695) Thanks @openperf, @chilu18, @Yipsh, @lbo728, and @s1korrrr. - WhatsApp/Web reconnect: treat close status
440as non-retryable (including string-form status values), stop reconnect loops immediately, and emit operator guidance to relink after resolving session conflicts. (#25858) Thanks @markmusson. - WhatsApp/Reasoning safety: suppress outbound payloads marked as reasoning and hard-drop text payloads that begin with
Reasoning:before WhatsApp delivery, preventing hidden thinking blocks from leaking to end users through final-message paths. (#25804, #25214, #24328) - Matrix/Read receipts: send read receipts as soon as Matrix messages arrive (before handler pipeline work), so clients no longer show long-lived unread/sent states while replies are processing. (#25841, #25840) Thanks @joshjhall.
- Telegram/Replies: when markdown formatting renders to empty HTML (for example syntax-only chunks in threaded replies), retry delivery with plain text, and fail loud when both formatted and plain payloads are empty to avoid false delivered states. (#25096, #25091) Thanks @Glucksberg.
- Telegram/Media fetch: prioritize IPv4 before IPv6 in SSRF pinned DNS address ordering so media downloads still work on hosts with broken IPv6 routing. (#24295, #23975) Thanks @Glucksberg.
- Telegram/Outbound API: replace Node 22's global undici dispatcher when applying Telegram
autoSelectFamilydecisions so outboundfetchcalls inherit IPv4 fallback instead of staying pinned to stale dispatcher settings. (#25682, #25676) Thanks @lairtonlelis. - Onboarding/Telegram: keep core-channel onboarding available when plugin registry population is missing by falling back to built-in adapters and continuing wizard setup with actionable recovery guidance. (#25803) Thanks @Suko.
- Android/Gateway auth: preserve Android gateway auth state across onboarding, use the native client id for operator sessions, retry with shared-token fallback after device-token auth failures, and avoid clearing tokens on transient connect errors.
- Slack/DM routing: treat
D*channel IDs as direct messages even when Slack sends an incorrectchannel_type, preventing DM traffic from being misclassified as channel/group chats. (#25479) Thanks @mcaxtr. - Zalo/Group policy: enforce sender authorization for group messages with
groupPolicy+groupAllowFrom(fallback toallowFrom), default runtime group behavior to fail-closed allowlist, and block unauthorized non-command group messages before dispatch. Thanks @tdjackey for reporting. - macOS/Voice input: guard all audio-input startup paths against missing default microphones (Voice Wake, Talk Mode, Push-to-Talk, mic-level monitor, tester) to avoid launch/runtime crashes on mic-less Macs and fail gracefully until input becomes available. (#2581...
openclaw 2026.2.24-beta.1
Immutable
release. Only release title and notes can be modified.
Changes
- Auto-reply/Abort shortcuts: expand standalone stop phrases (
stop openclaw,stop action,stop run,stop agent,please stop, and related variants), accept trailing punctuation (for exampleSTOP OPENCLAW!!!), add multilingual stop keywords (including ES/FR/ZH/HI/AR/JP/DE/PT/RU forms), and treat exactdo not do thatas a stop trigger while preserving strict standalone matching. (#25103) Thanks @steipete and @vincentkoc. - Android/App UX: ship a native four-step onboarding flow, move post-onboarding into a five-tab shell (Connect, Chat, Voice, Screen, Settings), add a full Connect setup/manual mode screen, and refresh Android chat/settings surfaces for the new navigation model.
- Talk/Gateway config: add provider-agnostic Talk configuration with legacy compatibility, and expose gateway Talk ElevenLabs config metadata for setup/status surfaces.
- Security/Audit: add
security.trust_model.multi_user_heuristicto flag likely shared-user ingress and clarify the personal-assistant trust model, with hardening guidance for intentional multi-user setups (sandbox.mode="all", workspace-scoped FS, reduced tool surface, no personal/private identities on shared runtimes). - Dependencies: refresh key runtime and tooling packages across the workspace (Bedrock SDK, pi runtime stack, OpenAI, Google auth, and oxlint/oxfmt), while intentionally keeping
@buape/carbonpinned.
Fixes
- Routing/Session isolation: harden followup routing so explicit cross-channel origin replies never fall back to the active dispatcher on route failure, preserve queued overflow summary routing metadata (
channel/to/thread) across followup drain, and prefer originating channel context over internal provider tags for embedded followup runs. This prevents webchat/control-ui context from hijacking Discord-targeted replies in shared sessions. (#25864) Thanks @Gamedesigner. - Security/Routing: fail closed for shared-session cross-channel replies by binding outbound target resolution to the current turn’s source channel metadata (instead of stale session route fallbacks), and wire those turn-source fields through gateway + command delivery planners with regression coverage. (#24571) Thanks @brandonwise.
- Heartbeat routing: prevent heartbeat leakage/spam into Discord and other direct-message destinations by blocking direct-chat heartbeat delivery targets and keeping blocked-delivery cron/exec prompts internal-only. (#25871)
- Heartbeat defaults/prompts: switch the implicit heartbeat delivery target from
lasttonone(opt-in for external delivery), and use internal-only cron/exec heartbeat prompt wording when delivery is disabled so background checks do not nudge user-facing relay behavior. (#25871, #24638, #25851) - Auto-reply/Heartbeat queueing: drop heartbeat runs when a session already has an active run instead of enqueueing a stale followup, preventing duplicate heartbeat response branches after queue drain. (#25610, #25606) Thanks @mcaxtr.
- Cron/Heartbeat delivery: stop inheriting cached session
lastThreadIdfor heartbeat-mode target resolution unless a thread/topic is explicitly requested, so announce-mode cron and heartbeat deliveries stay on top-level destinations instead of leaking into active conversation threads. (#25730) Thanks @markshields-tl. - Messaging tool dedupe: treat originating channel metadata as authoritative for same-target
message.sendsuppression in proactive runs (heartbeat/cron/exec-event), including synthetic-provider contexts, sodelivery-mirrortranscript entries no longer cause duplicate Telegram sends. (#25835) Thanks @jadeathena84-arch. - Channels/Typing keepalive: refresh channel typing callbacks on a keepalive interval during long replies and clear keepalive timers on idle/cleanup across core + extension dispatcher callsites so typing indicators do not expire mid-inference. (#25886, #25882) Thanks @stakeswky.
- Agents/Model fallback: when a run is currently on a configured fallback model, keep traversing the configured fallback chain instead of collapsing straight to primary-only, preventing dead-end failures when primary stays in cooldown. (#25922, #25912) Thanks @Taskle.
- Gateway/Models: honor explicit
agents.defaults.modelsallowlist refs even when bundled model catalog data is stale, synthesize missing allowlist entries inmodels.list, and allowsessions.patch//modelselection for those refs without falsemodel not allowederrors. (#20291) Thanks @kensipe, @nikolasdehor, and @vincentkoc. - Control UI/Agents: inherit
agents.defaults.model.fallbacksin the Overview fallback input when no per-agent model entry exists, while preserving explicit per-agent fallback overrides (including empty lists). (#25729, #25710) Thanks @Suko. - Automation/Subagent/Cron reliability: honor
ANNOUNCE_SKIPinsessions_spawncompletion/direct announce flows (no user-visible token leaks), add transient direct-announce retries for channel unavailability (for example WhatsApp listener reconnect windows), and includecronin thecodingtool profile so/tools/invokecan execute cron actions when explicitly allowed by gateway policy. (#25800, #25656, #25842, #25813, #25822, #25821) Thanks @astra-fer, @aaajiao, @dwight11232-coder, @kevinWangSheng, @widingmarcus-cyber, and @stakeswky. - Discord/Voice reliability: restore runtime DAVE dependency (
@snazzah/davey), add configurable DAVE join options (channels.discord.voice.daveEncryptionandchannels.discord.voice.decryptionFailureTolerance), clean up voice listeners/session teardown, guard against stale connection events, and trigger controlled rejoin recovery after repeated decrypt failures to improve inbound STT stability under DAVE receive errors. (#25861, #25372, #24883, #24825, #23890, #23105, #22961, #23421, #23278, #23032) - Discord/Block streaming: restore block-streamed reply delivery by suppressing only reasoning payloads (instead of all
blockpayloads), fixing missing Discord replies inchannels.discord.streaming=blockmode. (#25839, #25836, #25792) Thanks @pewallin. - Discord/Proxy + reactions + model picker: thread channel proxy fetch into inbound media/sticker downloads, use proxy-aware gateway metadata fetch for WSL/corporate proxy setups, wire
messages.statusReactions.{emojis,timing}into Discord reaction lifecycle control, and compact model-pickercustom_idkeys to stay under Discord's 100-char limit while keeping backward-compatible parsing. (#25232, #25507, #25564, #25695) Thanks @openperf, @chilu18, @Yipsh, @lbo728, and @s1korrrr. - WhatsApp/Web reconnect: treat close status
440as non-retryable (including string-form status values), stop reconnect loops immediately, and emit operator guidance to relink after resolving session conflicts. (#25858) Thanks @markmusson. - WhatsApp/Reasoning safety: suppress outbound payloads marked as reasoning and hard-drop text payloads that begin with
Reasoning:before WhatsApp delivery, preventing hidden thinking blocks from leaking to end users through final-message paths. (#25804, #25214, #24328) - Matrix/Read receipts: send read receipts as soon as Matrix messages arrive (before handler pipeline work), so clients no longer show long-lived unread/sent states while replies are processing. (#25841, #25840) Thanks @joshjhall.
- Telegram/Replies: when markdown formatting renders to empty HTML (for example syntax-only chunks in threaded replies), retry delivery with plain text, and fail loud when both formatted and plain payloads are empty to avoid false delivered states. (#25096, #25091) Thanks @Glucksberg.
- Telegram/Media fetch: prioritize IPv4 before IPv6 in SSRF pinned DNS address ordering so media downloads still work on hosts with broken IPv6 routing. (#24295, #23975) Thanks @Glucksberg.
- Telegram/Outbound API: replace Node 22's global undici dispatcher when applying Telegram
autoSelectFamilydecisions so outboundfetchcalls inherit IPv4 fallback instead of staying pinned to stale dispatcher settings. (#25682, #25676) Thanks @lairtonlelis. - Onboarding/Telegram: keep core-channel onboarding available when plugin registry population is missing by falling back to built-in adapters and continuing wizard setup with actionable recovery guidance. (#25803) Thanks @Suko.
- Android/Gateway auth: preserve Android gateway auth state across onboarding, use the native client id for operator sessions, retry with shared-token fallback after device-token auth failures, and avoid clearing tokens on transient connect errors.
- Slack/DM routing: treat
D*channel IDs as direct messages even when Slack sends an incorrectchannel_type, preventing DM traffic from being misclassified as channel/group chats. (#25479) Thanks @mcaxtr. - Zalo/Group policy: enforce sender authorization for group messages with
groupPolicy+groupAllowFrom(fallback toallowFrom), default runtime group behavior to fail-closed allowlist, and block unauthorized non-command group messages before dispatch. Thanks @tdjackey for reporting. - macOS/Voice input: guard all audio-input startup paths against missing default microphones (Voice Wake, Talk Mode, Push-to-Talk, mic-level monitor, tester) to avoid launch/runtime crashes on mic-less Macs and fail gracefully until input becomes available. (#25817) Thanks @sfo2001.
- macOS/IME input: when marked text is active, treat Return as IME candidate confirmation first in both the voice overlay composer and shared chat composer to prevent accidental sends while composing CJK text. (#25178) Thanks @bottotl.
- macOS/Voice wake routing: default forwarded voice-wake transcripts to the
webchatchannel (instead of ambiguouslastrouting) so local voice prompts stay pinned to the control chat surface unless explicitly overridden. (#25440) Thanks @chilu18. - macOS/Gateway launch: prefer an available
openclawbinary before pnpm/node runtime fallback when resolving local gateway commands, so local startup no longer fails on hosts with broken runtime d...
openclaw 2026.2.23
Immutable
release. Only release title and notes can be modified.
Changes
- Providers/Kilo Gateway: add first-class
kilocodeprovider support (auth, onboarding, implicit provider detection, model defaults, transcript/cache-ttl handling, and docs), with default modelkilocode/anthropic/claude-opus-4.6. (#20212) Thanks @jrf0110 and @markijbema. - Providers/Vercel AI Gateway: accept Claude shorthand model refs (
vercel-ai-gateway/claude-*) by normalizing to canonical Anthropic-routed model ids. (#23985) Thanks @sallyom, @markbooch, and @vincentkoc. - Docs/Prompt caching: add a dedicated prompt-caching reference covering
cacheRetention, per-agentparamsmerge precedence, Bedrock/OpenRouter behavior, and cache-ttl + heartbeat tuning. Thanks @svenssonaxel. - Gateway/HTTP security headers: add optional
gateway.http.securityHeaders.strictTransportSecuritysupport to emitStrict-Transport-Securityfor direct HTTPS deployments, with runtime wiring, validation, tests, and hardening docs. - Sessions/Cron: harden session maintenance with
openclaw sessions cleanup, per-agent store targeting, disk-budget controls (session.maintenance.maxDiskBytes/highWaterBytes), and safer transcript/archive cleanup + run-log retention behavior. (#24753) thanks @gumadeiras. - Tools/web_search: add
provider: "kimi"(Moonshot) support with key/config schema wiring and a corrected two-step$web_searchtool flow that echoes tool results before final synthesis, including citation extraction from search results. (#16616, #18822) Thanks @adshine. - Media understanding/Video: add a native Moonshot video provider and include Moonshot in auto video key detection, plus refactor video execution to honor
entry/config/providerbaseUrl+header precedence (matching audio behavior). (#12063) Thanks @xiaoyaner0201. - Agents/Config: support per-agent
paramsoverrides merged on top of model defaults (includingcacheRetention) so mixed-traffic agents can tune cache behavior independently. (#17470, #17112) Thanks @rrenamed. - Agents/Bootstrap: cache bootstrap file snapshots per session key and clear them on session reset/delete, reducing prompt-cache invalidations from in-session
AGENTS.md/MEMORY.mdwrites. (#22220) Thanks @anisoptera.
Breaking
- BREAKING: browser SSRF policy now defaults to trusted-network mode (
browser.ssrfPolicy.dangerouslyAllowPrivateNetwork=truewhen unset), and canonical config usesbrowser.ssrfPolicy.dangerouslyAllowPrivateNetworkinstead ofbrowser.ssrfPolicy.allowPrivateNetwork.openclaw doctor --fixmigrates the legacy key automatically.
Fixes
- Security/Config: redact sensitive-looking dynamic catchall keys in
config.getsnapshots (for exampleenv.*andskills.entries.*.env.*) and preserve round-trip restore behavior for those redacted sentinels. Thanks @merc1305. - Tests/Vitest: tier local parallel worker defaults by host memory, keep gateway serial by default on non-high-memory hosts, and document a low-profile fallback command for memory-constrained land/gate runs to prevent local OOMs. (#24719) Thanks @ngutman.
- WhatsApp/Group policy: fix
groupAllowFromsender filtering whengroupPolicy: "allowlist"is set without explicitgroups— previously all group messages were blocked even for allowlisted senders. (#24670) - Agents/Context pruning: extend
cache-ttleligibility to Moonshot/Kimi and ZAI/GLM providers (including OpenRouter model refs), socontextPruning.mode: "cache-ttl"is no longer silently skipped for those sessions. (#24497) Thanks @lailoo. - Doctor/Memory: query gateway-side default-agent memory embedding readiness during
openclaw doctor(instead of inferring from generic gateway health), and warn when the gateway memory probe is unavailable or not ready while keepingopenclaw configureremediation guidance. (#22327) thanks @therk. - Sessions/Store: canonicalize inbound mixed-case session keys for metadata and route updates, and migrate legacy case-variant entries to a single lowercase key to prevent duplicate sessions and missing TUI/WebUI history. (#9561) Thanks @hillghost86.
- Telegram/Reactions: soft-fail reaction action errors (policy/token/emoji/API), accept snake_case
message_id, and fallback to inbound message-id context when explicitmessageIdis omitted so DM reactions stay stable without regeneration loops. (#20236, #21001) Thanks @PeterShanxin and @vincentkoc. - Telegram/Polling: scope persisted polling offsets to bot identity and reuse a single awaited runner-stop path on abort/retry, preventing cross-token offset bleed and overlapping pollers during restart/error recovery. (#10850, #11347) Thanks @talhaorak, @anooprdawar, and @vincentkoc.
- Telegram/Reasoning: when
/reasoning offis active, suppress reasoning-only delivery segments and block raw fallback resend of suppressedReasoning:/<think>text, preventing internal reasoning leakage in legacy sessions while preserving answer delivery. (#24626, #24518) - Agents/Reasoning: when model-default thinking is active (for example
thinking=low), keep auto-reasoning disabled unless explicitly enabled, preventingReasoning:thinking-block leakage in channel replies. (#24335, #24290) thanks @Kay-051. - Agents/Reasoning: avoid classifying provider reasoning-required errors as context overflows so these failures no longer trigger compaction-style overflow recovery. (#24593) Thanks @vincentkoc.
- Agents/Models: codify
agents.defaults.model/agents.defaults.imageModelconfig-boundary input asstring | {primary,fallbacks}, split explicit vs effective model resolution, and fixmodels status --agentsource attribution so defaults-inherited agents are labeled asdefaultswhile runtime selection still honors defaults fallback. (#24210) thanks @bianbiandashen. - Agents/Compaction: pass
agentDirinto manual/compactcommand runs so compaction auth/profile resolution stays scoped to the active agent. (#24133) thanks @Glucksberg. - Agents/Compaction: pass model metadata through the embedded runtime so safeguard summarization can run when
ctx.modelis unavailable, avoiding repeated"Summary unavailable due to context limits"fallback summaries. (#3479) Thanks @battman21, @hanxiao and @vincentkoc. - Agents/Compaction: cancel safeguard compaction when summary generation cannot run (missing model/API key or summarization failure), preserving history instead of truncating to fallback
"Summary unavailable"text. (#10711) Thanks @DukeDeSouth and @vincentkoc. - Agents/Tools: make
session_statusread transcript-derived usage mid-turn and tail-read session logs for cache-aware context reporting without full-log scans. (#22387) Thanks @1ucian. - Agents/Overflow: detect additional provider context-overflow error shapes (including
input length+max_tokensexceed-context variants) so failures route through compaction/recovery paths instead of leaking raw provider errors to users. (#9951) Thanks @echoVic and @Glucksberg. - Agents/Overflow: add Chinese context-overflow pattern detection in
isContextOverflowErrorso localized provider errors route through overflow recovery paths. (#22855) Thanks @Clawborn. - Agents/Failover: treat HTTP 502/503/504 errors as failover-eligible transient timeouts so fallback chains can switch providers/models during upstream outages instead of retrying the same failing target. (#20999) Thanks @taw0002 and @vincentkoc.
- Auto-reply/Inbound metadata: hide direct-chat
message_id/message_id_fulland sender metadata only from normalized chat type (not sender-id sentinels), preserving group metadata visibility and preventing sender-id spoofed direct-mode classification. (#24373) thanks @jd316. - Auto-reply/Inbound metadata: move dynamic inbound
flags(reply/forward/thread/history) from system metadata to user-context conversation info, preventing turn-by-turn prompt-cache invalidation from flag toggles. (#21785) Thanks @aidiffuser. - Auto-reply/Sessions: remove auth-key labels from
/newand/resetconfirmation messages so session reset notices never expose API key prefixes or env-key labels in chat output. (#24384, #24409) Thanks @Clawborn. - Slack/Group policy: move Slack account
groupPolicydefaulting to provider-level schema defaults so multi-account configs inherit top-levelchannels.slack.groupPolicyinstead of silently overriding inheritance with per-accountallowlist. (#17579) Thanks @ZetiMente. - Providers/Anthropic: skip
context-1m-*beta injection for OAuth/subscription tokens (sk-ant-oat-*) while preserving OAuth-required betas, avoiding Anthropic 401 auth failures whenparams.context1mis enabled. (#10647, #20354) Thanks @ClumsyWizardHands and @dcruver. - Providers/DashScope: mark DashScope-compatible
openai-completionsendpoints assupportsDeveloperRole=falseso OpenClaw sendssysteminstead of unsupporteddeveloperrole on Qwen/DashScope APIs. (#19130) Thanks @Putzhuawa and @vincentkoc. - Providers/Bedrock: disable prompt-cache retention for non-Anthropic Bedrock models so Nova/Mistral requests do not send unsupported cache metadata. (#20866) Thanks @pierreeurope.
- Providers/Bedrock: apply Anthropic-Claude cacheRetention defaults and runtime pass-through for
amazon-bedrock/*anthropic.claude*model refs, while keeping non-Anthropic Bedrock models excluded. (#22303) Thanks @snese. - Providers/OpenRouter: remove conflicting top-level
reasoning_effortwhen injecting nestedreasoning.effort, preventing OpenRouter 400 payload-validation failures for reasoning models. (#24120) thanks @tenequm. - Providers/Groq: avoid classifying Groq TPM limit errors as context overflow so throttling paths no longer trigger overflow recovery logic. (#16176) Thanks @dddabtc.
- Gateway/WS: close repeated post-handshake
unauthorized role:*request floods per connection and sample duplicate rejection logs, preventing a single misbehaving client from degrading gateway responsiveness. (#20168) Thanks @acy103, @vibecodooor, and @vincentkoc. - Gateway/Restart: treat child listener PIDs a...
openclaw 2026.2.22
Immutable
release. Only release title and notes can be modified.
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...