=== OpenClaw Upgrade Verification ===
Waiting for container openclaw-upgrade-test to be ready...
✓ Container is responsive (waiting for init to complete...)
✓ s6 init complete (crond up)
✓ Version: 2026.3.11
✓ Config is valid JSON
FAIL: tools.profile is 'null' (expected 'coding')
✓ Config owned by openclaw
✓ Auth mode: token
✓ Gateway process running
✓ Tailscale binary present
Waiting for gateway HTTP...
✓ Gateway HTTP: 200
✓ Config writable by openclaw user
✓ Channel plugins loaded: discord,signal,telegram,whatsapp
✓ Backup config (backup.yaml) is valid
WARN: pnpm store may not be excluded from backups
SKIP: Telegram channel probe (TELEGRAM_BOT_TOKEN not set)
✓ openclaw doctor completes
=== Upgrade Verification Results ===
Passed: 11
Failed: 1
Warnings: 1
=== UPGRADE VERIFICATION FAILED (1 failures) ===
Automated Upgrade Failed: 2026.2.9 → 2026.3.11
Failed stage: Docker smoke tests
Workflow run: https://github.com/vhrahulkumar/openclaw-appplatform/actions/runs/23508975503
Test Output
Known Regressions
Release Notes
2026.3.23
Breaking
Changes
Qwen (Alibaba Cloud Model Studio). (#43878)btn--icon,btn--ghost,btn--xs), refine the Knot theme to a black-and-red palette with WCAG 2.1 AA contrast, add config icons for Diagnostics/CLI/Secrets/ACP/MCP sections, replace the roundness slider with discrete stops, and improve accessibility with aria-labels across usage filters. (#53272) Thanks @BunsDev.<script>blocks in the servedindex.htmland include them in thescript-srcCSP directive, keeping inline scripts blocked by default while allowing explicitly hashed bootstrap code. (#53307) Thanks @BunsDev.Fixes
light-runtime-api.js, Matrixruntime-api.js, and other plugin runtime entry files in the npm package again, so global installs stop failing on missing bundled plugin runtime surfaces.channels login/logout, harden channel ids against prototype-chain and control-character abuse, and fall back cleanly to catalog-backed channel installs, so channel auth works again for single-channel setups and on-demand channel installs. (#53254) Thanks @BunsDev.models auth paste-tokenwrite to the resolved agent store, so Configure, Onboard, and token-paste flows stop snapping back to expired OpenAI tokens. Fixes #53207. Related to #45516.operator.readfallback message when a connection really lacks read scope, so operator sessions stop failing or blanking on read-backed pages. (#53110) Thanks @BunsDev.>=2026.3.22ClawHub package checks so installs no longer fail behind the stale1.2.0constant. (#53157) Thanks @futhgar.clawhub:specs and versionless ClawHub package names as uninstall targets, soopenclaw plugins uninstall clawhub:<package>works again even when the recorded install was pinned to a version.web_searchprovider instead of stale/default selection, so agent turns keep hitting the provider you actually configured. Fixes #53020. Thanks @jzakirov.openclaw doctor --fixto repair old persisted Mistral provider configs that still carry context-sized output limits, avoiding deterministic Mistral 422 rejects on fresh and existing setups. Fixes #52599. Thanks @vincentkoc.openclaw skills ...and gateway skill browsing keep using the signed-in auth state instead of silently falling back to unauthenticated mode. Fixes #53034.2026.3.23-2is read by2026.3.23, while still warning for truly newer or incompatible versions.openclaw cron add|edit --at ... --tz <iana>honor the requested local wall-clock time for offset-less one-shot datetimes, including DST boundaries, and keep--tzrejected for--every. (#53224) Thanks @RolfHegr.allowFromresolution hits unresolved SecretRef-backed accounts, and fail closed only for the affected provider inference path. (#52791) Thanks @Lukavyi.api_errorpayloads as retryable only when they include transient failure signals, so MiniMax-style backend failures still trigger model fallback without misclassifying billing, auth, or format/context errors. (#49611) Thanks @ayushozha.line-runtimestar export so jiti no longer throwsTypeError: Cannot redefine propertyon startup. (#53221) Thanks @Drickon.currentThreadTsin the threading tool-context fallback for Telegram DM topics so thread-aware tools still receive the active topic context when the main thread metadata is missing. (#52217)botNamewithnamein the channel config examples so the docs match the strict account schema for per-account display names. (#52753) Thanks @haroldfabla2-hue.openclaw doctor --fixremove staleplugins.allowandplugins.entriesrefs left behind after plugin removal. Thanks @sallyomInvalid skill slugerrors duringopenclaw skills update. (#53206) Thanks @drobison00.componentsand Slackblocksoptional again, and route Feishumessage(..., media=...)sends through the outbound media path, so pin/unpin/react flows stop failing schema validation and Feishu file/image attachments actually send. Fixes #52970 and #52962. Thanks @vincentkoc.openrouter/autopricing refresh from recursing indefinitely during bootstrap, so OpenRouter auto routes can populate cached pricing andusage.costagain. Fixes #53035. Thanks @vincentkoc.plugins.slots.memory="memory-lancedb"works again after global npm installs without moving LanceDB into OpenClaw core dependencies. Fixes #26100.plugins.allowids as warnings instead of fatal config errors, so recovery commands likeplugins install,doctor --fix, andstatusstill run when a plugin is missing locally. Fixes #52992. Thanks @vincentkoc.whatsapptoplugins.allow, soopenclaw doctor --fixno longer writes schema-invalid plugin allowlist entries when repairing built-in channels. Fixes #52931. Thanks @vincentkoc.asDocumentas a user-facing alias forforceDocumenton image and GIF sends, while preserving explicitforceDocumentprecedence when both flags are present. (#52461) Thanks @bakhtiersizhaev.skills.entries.<skill>.apiKeySecretRefs resolve correctly during embedded startup instead of failing on raw source config. Fixes #53098. Thanks @vincentkoc.resolveMatrixAccountStringValuesruntime-api exports under Jiti so bundled Matrix installs no longer crash at startup withCannot redefine property: resolveMatrixAccountStringValues. Fixes #52909 and #52891. Thanks @vincentkoc.$0/$ntokens, disallowing newline-separatedexec, and still acceptingexec --carrier forms. Thanks @vincentkoc.openclaw 2026.3.22
2026.3.22
Breaking
openclaw plugins install <package>now prefers ClawHub before npm for npm-safe names, and only falls back to npm when ClawHub does not have that package or version. Docs: https://docs.openclaw.ai/tools/clawhubdriver: "extension", andbrowser.relayBindHost. Runopenclaw doctor --fixto migrate host-local browser config toexisting-session/user; Docker, headless, sandbox, and remote browser flows still use raw CDP. Docs: https://docs.openclaw.ai/gateway/doctor and https://docs.openclaw.ai/tools/browser (#47893) Thanks @vincentkoc.image_generatetool. The oldnano-banana-prodocs/examples are gone; if you previously copied that sample-skill config, switch toagents.defaults.imageGenerationModelfor built-in image generation or install a separate third-party skill explicitly.nano-banana-proskill wrapper. Useagents.defaults.imageGenerationModel.primary: "google/gemini-3-pro-image-preview"for the native Nano Banana-style path instead.openclaw/plugin-sdk/*;openclaw/extension-apiis removed with no compatibility shim. Bundled plugins must use injected runtime for host-side operations (for exampleapi.runtime.agent.runEmbeddedPiAgent) and any remaining direct imports must come from narrowopenclaw/plugin-sdk/*subpaths instead of the monolithic SDK root. Docs: https://docs.openclaw.ai/plugins/sdk-migration and https://docs.openclaw.ai/plugins/sdk-overviewChannelMessageActionAdapter.describeMessageTool(...)for sharedmessagetool discovery. The legacylistActions,getCapabilities, andgetToolSchemaadapter methods are removed. Plugin authors should migrate message discovery todescribeMessageTool(...)and keep channel-specific action runtime code inside the owning plugin package. Thanks @gumadeiras.matrix-js-sdk. If you are upgrading from the previous public Matrix plugin, follow the migration guide: https://docs.openclaw.ai/install/migrating-matrix Thanks @gumadeiras.CLAWDBOT_*andMOLTBOT_*compatibility env names across runtime, installers, and test tooling. Use the matchingOPENCLAW_*env names instead..moltbotstate-dir andmoltbot.jsonauto-detection/migration fallback. If you still keep state under~/.moltbot, move it to~/.openclawor setOPENCLAW_STATE_DIR/OPENCLAW_CONFIG_PATHexplicitly. Docs: https://docs.openclaw.ai/install/migrating and https://docs.openclaw.ai/start/getting-startedMAVEN_OPTS,SBT_OPTS,GRADLE_OPTS,ANT_OPTS), glibc tunable exploitation (GLIBC_TUNABLES), and .NET dependency resolution hijack (DOTNET_ADDITIONAL_DEPS) from the host exec environment, and restrict Gradle init script redirect (GRADLE_USER_HOME) as an override-only block so user-configured Gradle homes still propagate. (#49702)timeas a transparent dispatch wrapper during allowlist evaluation and allow-always persistence so approvedtime ...commands bind the inner executable instead of the wrapper path. Thanks @YLChen-007 for reporting.64 KB/5s, and cap concurrent pre-auth requests per source IP so unauthenticated callers cannot force the old1 MB/30sbuffering path. Thanks @SEORY0 for reporting.details.mediaso generated media keeps attaching to assistant replies after the collect-then-attach refactor. (#51731) Thanks @christianklotz.%and_in contact-name queries so searches like100%or_idno longer match unrelated contacts through SQLLIKEwildcards. (#41891) Thanks @Kaneki-x.Changes
openclaw skills search|install|updateflows plusopenclaw plugins install clawhub:<package>with tracked update metadata, gateway skill-install/update support for ClawHub-backed requests, and regression coverage/docs for the new source path.plugin@marketplaceinstalls, marketplace listing, and update support, plus Docker E2E coverage for local and official marketplace flows. (#48058) Thanks @vincentkoc./pluginsand/pluginchat commands for plugin list/show and enable/disable flows, alongside explicitcommands.pluginsconfig gating. Thanks @vincentkoc.mainviaopenclaw update --tag main, installer--version main, or direct npm/pnpm git specs. (#47630) Thanks @vincentkoc.settings.jsondefaults to embedded Pi with shell overrides sanitized.openclaw plugins, keepopenclaw hooksfocused on hook visibility and per-hook controls, and show plugin-managed hook details in CLI output.openai/gpt-5.4, keep Codex onopenai-codex/gpt-5.4, and centralize OpenAI chat, image, TTS, transcription, and embedding defaults in one shared module so future default-model updates stay low-churn. Thanks @vincentkoc./btwside questions for quick tool-less answers about the current session without changing future session context, with dismissible in-session TUI answers and explicit BTW replies on external channels. (#45444) Thanks @ngutman.mirrorandremoteworkspace modes, and make sandbox list/recreate/prune backend-aware instead of Docker-only.mirrormode.browser.profiles.<name>.userDataDirso Chrome DevTools MCP can attach to Brave, Edge, and other Chromium-based browsers through their own user data directories. (#48170) Thanks @velvet-shark.anthropic-vertexprovider support for Claude via Google Vertex AI, including GCP auth/discovery and main run-path routing. (#43356) Thanks @sallyom and @yossiovadia.plugins.entries.exa.config.webSearch.*. Thanks @V-Gutierrez and @vincentkoc.tavily_searchandtavily_extracttools, using canonical plugin-owned config underplugins.entries.tavily.config.webSearch.*. (#49200) thanks @lakshyaag-tavily.onboard/configure search provider via a bundled plugin, expose explicitfirecrawl_searchandfirecrawl_scrapetools, and align coreweb_fetchfallback behavior with Firecrawl base-URL/env fallback plus guarded endpoint fetches.gpt-5.4-miniandgpt-5.4-nanoin the OpenAI provider catalog, runtime resolution, and reasoning capability gates. Thanks @vincentkoc.talk.speak, keep Talk secrets on the gateway, and switch Android playback to final-response audio instead of device-local ElevenLabs streaming. (#50849)callLog.searchplus shared Call Log permission wiring so Android nodes can search recent call history through the gateway. (#44073) Thanks @lixuankai.sms.searchplus shared SMS permission wiring so Android nodes can search device text messages through the gateway. (#48299) Thanks @lixuankai.autoTopicLabeloverrides. (#51502) Thanks @Lukavyi.topic-editfor forum-topic renames and icon updates while sharing the same Telegram topic-edit transport used by the plugin runtime. (#47798) Thanks @obviyus.channels.telegram.silentErrorRepliessetting so bot error replies can be delivered silently across regular replies, native commands, and fallback sends. (#19776) Thanks @ImLukeF.onReasoningStreamandonReasoningEndsupport to streaming cards, so/reasoning streamrenders thinking tokens as markdown blockquotes in the same card — matching the Telegram channel's reasoning lane behavior. (#46029) Thanks @day253.allowBotsroom policy so configured Matrix bot accounts can talk to each other, with optional mention-only gating. Thanks @gumadeiras.allowPrivateNetworkopt-in for private/internal homeservers, while keeping public cleartext homeservers blocked. Thanks @gumadeiras./fastandparams.fastModeto MiniMax-highspeedmodels for M2.1, M2.5, and M2.7 API-key and OAuth runs. Thanks @vincentkoc.MiniMax-M2,MiniMax-M2.1, andMiniMax-M2.1-highspeedcatalog entries so OpenClaw's provider metadata and OAuth aliases stay aligned with the current upstream Pi SDK. Thanks @vincentkoc.minimaxplugin, while keeping legacyminimax-portal-authconfig ids aliased for compatibility./fastandparams.fastModeto the current xAI Grok fast model family so direct Grok runs can opt into the faster Pi-backed variants. Thanks @vincentkoc.config setwith SecretRef and provider builder modes, JSON/batch assignment support, and--dry-runvalidation with structured JSON output. (#49296) Thanks @joshavant./v1OpenAI-compatible endpoint and add MiMo V2 Pro plus MiMo V2 Omni to the built-in catalog. (#49214) thanks @DJjjjhao.healthMonitor.enabledoverrides, while keeping the existing global disable path ongateway.channelHealthCheckMinutes=0. (#42107) Thanks @rstar327.onConversationBindingResolved(...)so plugins can react immediately after bind approvals or denies without blocking channel interaction acknowledgements. (#48678) Thanks @huntharo.delegateCompactionToRuntime(...)on the public plugin SDK, refactor the legacy engine to use the shared helper, and clarifyownsCompactiondelegation semantics for non-owning engines. (#49061) Thanks @jalehman.modelIdinto context-engineassemble()so plugins can adapt context formatting per model. (#47437) thanks @jscianna.maxSkillsPromptChars. (#47553) Thanks @snese.<workspace>/hooksdisabled until explicitly enabled, block workspace hook name collisions from shadowing bundled/managed/plugin hooks, and treathooks.internal.load.extraDirsas trusted managed hook sources.allowUrl: falseas the deny-all switch, and add regression coverage for the normalization path.dist/cli/memory-cli.jsas a stable core entry so runtimememory_searchloading no longer depends on hashedmemory-cli-*bundle names. (#51759) Thanks @oliviareid-svg.openclaw/plugin-sdk/testingsurface for plugin-author test helpers, and move bundled-extension-only test bridges out ofextensions/into private repo test helpers.src/commands/doctor/providers/*by extracting Telegram first-run and group allowlist warnings into a provider-specific module, keeping the current setup guidance and warning behavior intact. Thanks @vincentkoc.Fixes
file://media URLs and UNC/network paths before local filesystem resolution in core media loading and adjacent prompt/sandbox attachment seams, so the next release no longer allows structured local-media inputs to trigger outbound SMB credential handshakes on Windows. Thanks @RacerZ-fighting for reporting.gateway statusso TXT-only hints can no longer steer routing or SSH auto-target selection. Thanks @nexrin for reporting.memory_searchandmemory_getindependently so one unavailable memory tool no longer suppresses the other in new sessions. (#50198) Thanks @artwalker.contentsoptions, while fixing the result-count cap to honor Exa's higher limit. Thanks @vincentkoc.KeyedAsyncQueueimports onto the stableplugin-sdk/coresurface so Matrix Docker/runtime builds do not depend on the brittle keyed-async-queue subpath. Thanks @ecohash-co and @vincentkoc.user_idby default, and gate mutable username/nickname recipient lookup behinddangerouslyAllowNameMatchingwith new regression coverage. Thanks @nexrin.600sto48hso long-running ACP and agent sessions do not fail unless you configure a shorter limit.dist/extensionsentries in built installs, so gateway boot no longer recompiles bundled extension TypeScript on every startup and WhatsApp-class cold starts drop back to seconds instead of tens of seconds or worse. (#47560) Thanks @ngutman.Unknown model: openai-codex/gpt-5.4. Thanks @vincentkoc.openclaw configureno longer stalls after the banner while eagerly loading channel plugins. (#46301) Thanks @scoootscooob.tool_call_idvalues with HTTP 400. (#40996) Thanks @xaeon2026.prompt_cache_keyandprompt_cache_retentionfor non-OpenAI-compatible Responses endpoints while keeping them on direct OpenAI and Azure OpenAI paths, so third-party OpenAI-compatible providers no longer reject those requests with HTTP 400. (#49877) Thanks @ShaunTsai.strictfields unless users explicitly opt back in, so tool calling keeps working on providers that reject that option. (#45497) Thanks @sahancava./api/v1/models. (#45824) Thanks @DJjjjhao.allow_sending_without_replyon reply-targeted sends and media-error notices so deleted parent messages no longer drop otherwise valid replies. (#52524) Thanks @moltbot886.getUpdatesrequests so wedged network paths fail over sooner instead of waiting for the polling stall watchdog. Thanks @vincentkoc.Already resumed. (#52318) Thanks @Kaneki-x.443while preserving direct cleartext gateway defaults and explicit:80manual endpoints in onboarding. (#43540) Thanks @fmercurio.status --jsonstdout clean by skipping plugin compatibility scans that were not rendered in the JSON payload. (#52449) Thanks @cgdusek.Longtimestamps correctly, so fresh post-reconnect append messages are processed while stale history sync stays suppressed. (#42588) Thanks @MonkeyLeeT.515pairing restarts in both QR login andchannels loginflows, and keep the restart coverage pinned to the real wrapped error shape plus per-account creds queues. (#27910) Thanks @asyncjason.camera.snapso repeated captures do not leak native image memory. (#41902) Thanks @Kaneki-x.tmp-openclaw-dir. (#48469) Fixes #48062. Thanks @7inspire.disconnected (1006): no reason. (#46580) Fixes #46532. Thanks @vincentkoc.