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 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 originating conversation before consuming pending uploads, preventing cross-conversation pending-file upload or cancellation via leakeduploadIdvalues; includes regression coverage for match/mismatch invoke handling. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Gateway: harden
agents.filespath handling to block out-of-workspace symlink targets foragents.files.get/agents.files.set, keep in-workspace symlink targets supported, and add gateway regression coverage for both blocked escapes and allowed in-workspace symlinks. Thanks @tdjackey for reporting. - Security/Workspace FS: reject hardlinked workspace file aliases in
tools.fs.workspaceOnlyandtools.exec.applyPatch.workspaceOnlyboundary checks (including sandbox mount-root guards) to prevent out-of-workspace read/write via in-workspace hardlink paths. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Browser temp paths: harden trace/download output-path handling against symlink-root and symlink-parent escapes with realpath-based write-path checks plus secure fallback tmp-dir validation that fails closed on unsafe fallback links. This ships in the next npm release (
2026.2.25). Thanks @tdjackey for reporting. - Security/Browser uploads: revalidate upload paths at use-time in Playwright file-chooser and direct-input flows so missing/rebound paths are rejected before
setFiles, with regression coverage for strict missing-path handling. - Security/Exec approvals: bind
system.runapproval matching to exact argv identity and preserve argv whitespace in rendered command text, preventing trailing-space executable path swaps from reusing a mismatched approval. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Exec approvals: harden approval-bound
system.runexecution on node hosts by rejecting symlinkcwdpaths and canonicalizing path-like executable argv before spawn, blocking mutable-cwd symlink retarget chains between approval and execution. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Signal: enforce DM/group authorization before reaction-only notification enqueue so unauthorized senders can no longer inject Signal reaction system events under
dmPolicy/groupPolicy; reaction notifications now require channel access checks first. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Discord reactions: enforce DM policy/allowlist authorization before reaction-event system enqueue in direct messages; Discord reaction handling now also honors DM/group-DM enablement and guild
groupPolicychannel gating to keep reaction ingress aligned with normal message preflight. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Slack reactions + pins: gate
reaction_*andpin_*system-event enqueue through shared sender authorization so DMdmPolicy/allowFromand channelusersallowlists are enforced consistently for non-message ingress, with regression coverage for denied/allowed sender paths. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Telegram reactions: enforce
dmPolicy/allowFromand group allowlist authorization onmessage_reactionevents before enqueueing reaction system events, preventing unauthorized reaction-triggered input in DMs and groups; ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Telegram group allowlist: fail closed for group sender authorization by removing DM pairing-store fallback from group allowlist evaluation; group sender access now requires explicit
groupAllowFromor per-group/per-topicallowFrom. (#25988) Thanks @bmendonca3. - Security/Slack interactions: enforce channel/DM authorization and modal actor binding (
private_metadata.userId) before enqueueingblock_action/view_submission/view_closedsystem events, with regression coverage for unauthorized senders and missing/mismatched actor metadata. This ships in the next npm release (2026.2.25). Thanks @tdjackey for reporting. - Security/Nextcloud Talk: drop replayed signed webhook events with persistent per-account replay dedupe across restarts, and reject unexpected webhook backend origins when account base URL is configured. Thanks @aristorechina for reporting.
- Security/Nextcloud Talk: reject unsigned webhook traffic before full body reads, reducing unauthenticated request-body exposure, with auth-order regression coverage. (#26118) Thanks @bmendonca3.
- Security/Nextcloud Talk: stop treating DM pairing-store entries as group allowlist senders, so group authorization remains bounded to configured group allowlists. (#26116) Thanks @bmendonca3.
- Security/LINE: cap unsigned webhook body reads before auth/signature handling to bound unauthenticated body processing. (#26095) Thanks @bmendonca3.
- Security/IRC: keep pairing-store approvals DM-only and out of IRC group allowlist authorization, with policy regression tests for allowlist resolution. (#26112) Thanks @bmendonca3.
- Security/Microsoft Teams: isolate group allowlist and command authorization from DM pairing-store entries to prevent cross-context authorization bleed. (#26111) Thanks @bmendonca3.
- Security/SSRF guard: classify IPv6 multicast literals (
ff00::/8) as blocked/private-internal targets in shared SSRF IP checks, preventing multicast literals from bypassing URL-host preflight and DNS answer validation. This ships in the next npm release (2026.2.25). Thanks @zpbrent for reporting. - Tests/Low-memory stability: disable Vitest
vmForksby default on low-memory local hosts (<64 GiB), keep low-profile extension lane parallelism at 4 workers, and align cron isolated-agent tests withsetSessionRuntimeModelusage to avoid deterministic suite failures. (#26324) Thanks @ngutman.