OpenClaw v2026.3.31: Six Breaking Changes, a Real Task System, and a Security Hardening Spree

A week after v2026.3.24 cleaned up operational friction, v2026.3.31 drops six breaking changes and the longest changelog I’ve seen from this project. This is not a polish release. This is an architecture release with real migration consequences.

I’m running OpenClaw on bare metal Ubuntu 24.04 with Discord as the primary channel, Opus 4.6 for orchestration, GPT 5.4 on the coder agent, Ollama local for embeddings, and multiple sub-agents delegating work through ACP and sessions_spawn. From that angle, this release is split into three stories: a major task system upgrade that I’ve been wanting, a security hardening pass that’s going to bite people who weren’t paying attention, and a pile of channel improvements I mostly don’t need but someone will love.

Here’s the breakdown.

The Good

Background Tasks Finally Have a Brain

This is the headline feature for anyone running multi-agent workflows.

Previously, background tasks were basically ACP-only bookkeeping. Cron jobs, sub-agents, and background CLI execution all lived in separate tracking systems. If a sub-agent spawned from a cron job that itself spawned a child task, you had no unified view of what was running, what finished, or what got lost.

v2026.3.31 unifies all of it under a single SQLite-backed ledger. ACP runs, sub-agent spawns, cron executions, and background CLI work all flow through one control plane. There’s a new openclaw flows CLI surface (list, show, cancel) that gives you actual visibility into task orchestration.

The practical impact: when a coder agent spawns from a cron job and its child task gets blocked on an approval, the system now tracks that chain. Blocked tasks carry a parent-level reason. When you retry, it reopens the same flow instead of fragmenting into a new job. Task results route back through the intended parent thread or session instead of just announcing as a raw child task.

For my setup with Opus orchestrating GPT 5.4 sub-agents, this is the difference between “it worked, I think” and actually being able to trace what happened. The openclaw flows command alone would have saved me hours of debugging over the past month.

MCP Gets HTTP Transport and Better Tool Naming

Two MCP improvements worth calling out.

First, you can now point mcp.servers at a remote HTTP or SSE URL with auth headers. Previously, MCP servers had to be local stdio processes. This opens the door to hosted MCP services without proxying through a local wrapper. If you’re running MCP servers on a different machine (or using a third-party hosted MCP endpoint), this removes a significant friction point.

Second, bundled MCP tools now materialize with provider-safe names using the serverName__toolName pattern. This sounds minor until you’ve debugged a tool name collision between two MCP servers that both expose a search tool. The double-underscore namespacing makes tool routing unambiguous.

Connection timeouts per MCP server are also configurable now, which matters for flaky or slow remote servers.

Idle Stream Timeout for Stalled Models

A configurable idle-stream timeout for embedded runner requests means stalled model streams abort cleanly instead of hanging until the broader run timeout fires. If you’ve ever watched a session freeze because a model provider’s stream just stopped sending tokens without closing the connection, this fix is for you.

Previously, the only recourse was waiting for the full run timeout (which might be 5 or 10 minutes) or manually killing the session. Now the idle timeout catches the stall early and lets retry or fallback logic take over.

Anthropic Failover Gets Smarter

Anthropic’s “An unexpected error occurred while processing the response” errors are now treated as transient instead of terminal. Retry and fallback logic can engage instead of the whole turn dying on what’s usually a temporary server-side hiccup.

This is a quality-of-life fix that’s easy to overlook, but if you’re running Opus 4.6 as your primary model like I am, you’ve definitely seen this error during peak load. Having it auto-retry instead of failing the turn is a real improvement.

The new memorySearch.qmd.extraCollections config lets agents opt into searching other agents’ session transcripts without merging everything into one namespace. If you’re running multiple specialized agents (a coder, a researcher, an orchestrator), each can now selectively search the others’ conversation history when context would help.

For multi-agent setups, this is a building block toward agents that actually learn from each other’s sessions instead of each one starting blind.

The Bad (Breaking Changes That Will Bite You)

Six breaking changes. Some are fine. Some will break your setup if you update without reading.

Gateway Auth Gets Strict

The big one. trusted-proxy now rejects mixed shared-token configs, and local-direct fallback requires the configured token instead of implicitly authenticating same-host callers.

Translation: if you were running on localhost and never set a gateway token because “it’s local, who cares,” your agent might stop authenticating after the update. The implicit trust for same-host callers is gone. Set a token.

This is the right call from a security perspective, but it’s going to catch people who set up OpenClaw on a single machine and never touched the auth config. If your agent stops responding after updating, check your gateway auth first.

Exec Defaults Got Tightened, Then Obfuscation Detection Made It Worse (This One Bit Me Twice)

This is the breaking change I actually hit in production. It has two layers, and fixing the first one doesn’t fix the second.

Layer 1: New default exec policy. v2026.3.31 changed the default exec approval policy from permissive to allowlist plus ask-on-miss. If your openclaw.json doesn’t have an explicit tools.exec section and your exec-approvals.json has empty defaults, the agent starts prompting for approval on every shell command. My agent went from running freely to getting blocked on basic operations like checking a file or running git status.

The config fix:

// openclaw.json
"tools": {
  "exec": { "security": "full", "ask": "off" }
}

// exec-approvals.json
"defaults": { "security": "full", "ask": "off" }

Both layers must agree. The stricter one wins. This keeps the security allowlist enforced but disables interactive approval prompts.

Layer 2: Hardcoded obfuscation detection. Even after setting ask: "off", commands were still being blocked. The reason: 3.31 added a detectCommandObfuscation() function that flags commands as suspicious based on:

  • Command length over 10,000 characters
  • Hex-encoded strings
  • Base64 payloads with decode calls
  • Curl-pipe-shell patterns
  • Heredoc segments
  • Inline eval arguments

When any of these fire, the code unconditionally forces approval regardless of your ask setting:

const requiresAsk = requiresExecApproval({...})
  || requiresHeredocApproval
  || requiresInlineEvalApproval
  || obfuscation.detected;  // ignores ask:"off"

This exists in two separate code paths: the gateway exec path and the node exec path. There is no config knob to disable it.

AI agents routinely generate commands that trip these heuristics. A Python one-liner with JSON processing hits the heredoc or eval detection. A long curl command with piped output gets flagged. A base64-encoded config payload triggers the decode detection. These are normal agent operations, not obfuscation attempts.

The 10,000 character limit for “command too long” is particularly aggressive. Agents regularly build multi-step shell commands or inline Python scripts that exceed 10K characters without doing anything suspicious.

The fix required patching the source. Three changes to the distributed JavaScript:

  1. Raised MAX_COMMAND_CHARS from 10,000 to 1,000,000
  2. Removed the obfuscation override from the gateway exec approval gate
  3. Removed the same override from the node exec path

I wrote a patch script that applies all three changes and can be re-run after future npm update -g openclaw upgrades. That’s not a solution. That’s a workaround for a design decision that treats AI agent operators the same as untrusted third-party callers.

The obfuscation detection makes sense for hosted, multi-tenant deployments where you don’t trust the caller. It makes no sense for self-hosted, single-operator setups where the owner has already set ask: "off" because they trust their own agent. The ask setting should be the final word. Right now it isn’t.

If you update to 3.31 and your agent can run simple commands but still gets blocked on anything with heredocs, base64, eval, or long command strings, this is why. You’ll need to patch or wait for upstream to add a config override.

Plugin and Skill Installs Fail Closed

Plugin installs and skill dependency installs that previously succeeded despite dangerous-code findings will now fail by default. You’ll need --dangerously-force-unsafe-install to override.

If you install skills from ClawHub or use community plugins, some of them might fail to install until their authors clean up the flagged patterns. This is the kind of change that’s correct in principle but annoying in practice if you’re relying on a skill that triggers a false positive.

Node Trust Model Tightened

Two related changes. Node commands stay disabled until pairing is approved (device pairing alone no longer exposes them). And node-originated runs get a reduced trust surface, so notification-driven or node-triggered flows that relied on broader host/session tool access may break.

If you’re running OpenClaw with companion apps on Android or iOS and you have automation triggered by phone notifications, test it after updating. The reduced trust surface might cut off tools your notification flows were using.

Legacy Plugin SDK Paths Deprecated

The old provider compat subpaths and bundled provider setup shims are deprecated with migration warnings. They’ll be removed in a future major release. If you wrote custom plugins against the old SDK paths, start migrating.

Nodes.run Removed

The duplicated nodes.run shell wrapper is gone. Node shell execution now goes exclusively through exec host=node. If you had scripts or workflows calling nodes.run directly, switch them to the exec path.

The Ugly

Exec Approvals Are Still Painful on Discord

This release adds native Slack exec approval routing, which is great for Slack users. Discord still doesn’t have it. The release does infer Discord exec approvers from existing owner config when execApprovals.approvers is unset, and extends the default approval window to 30 minutes. But the core pain point remains: if you’re on Discord and your agent needs to run a shell command, you’re either approving from the Web UI or the terminal.

I hit this while writing this very post. Asked my agent to check the local OpenClaw version, got blocked by exec approval, couldn’t approve from Discord. Had to fix the exec defaults AND patch the obfuscation detection (see the breaking changes section above) before I could continue. Slack gets native approval buttons this release. Discord gets “go use the Web UI.” The gap is getting wider.

The Changelog Is Dense to the Point of Hostility

This release has roughly 80 individual changes. That’s a lot even for a weekly release cadence. The changelog descriptions are accurate but written for developers who already know the codebase. Lines like “route one-task ACP and subagent updates through a parent task-flow owner context, so detached work can emerge back through the intended parent thread/session instead of speaking only as a raw child task” are technically precise but require three re-reads to understand what actually changed for you as a user.

The project would benefit from a “what actually changed for operators” summary alongside the developer changelog. Right now, figuring out which of the 80 changes matter for your deployment is homework.

Security Fixes Reveal How Much Was Wrong

The volume of security fixes in this release is impressive and a little alarming. Blocked proxy, TLS, and Docker endpoint env overrides in host exec. Blocked Python package index override variables. Sanitized SSH subprocess env vars. Hardened SecretRef redaction. Tightened gateway auth rate limiting during WebSocket handshakes. Fixed Discord voice authorization bypass. Rejected mismatched browser Origin headers.

Each of these fixes is good. Taken together, they paint a picture of a trust surface that had more holes than the project probably wants to admit. The exec environment alone had at least four separate vectors for redirecting traffic or trust roots through request-scoped env overrides.

Credit where it’s due: they’re fixing it aggressively and the security research acknowledgments suggest active external auditing. But if you’re running an older version of OpenClaw exposed to the internet, update today.

What Matters for Our Stack

Running through the lens of my specific setup (bare metal Ubuntu, Discord, Opus + GPT 5.4 multi-agent, Ollama local):

Immediately useful:

  • Unified task control plane and openclaw flows CLI. I’ve wanted this for weeks.
  • Anthropic failover treating transient errors as retryable. No more dead turns during API hiccups.
  • Idle stream timeout. Stalled model connections no longer hang the session.
  • MCP HTTP transport. Can point MCP configs at remote servers now.
  • Cross-agent memory search collections. Building block for smarter multi-agent setups.

Already hit and fixed:

  • Exec defaults tightened. Had to add explicit tools.exec policy to openclaw.json and set defaults in exec-approvals.json. Without both, the agent prompts for approval on every shell command.
  • Obfuscation detection overriding ask: "off". Had to patch three locations in the distributed JavaScript to make the config setting actually respected. Built a re-runnable patch script for future updates.

Need to verify:

  • Gateway auth changes. My setup uses a configured token, but the local-direct fallback change could affect headless callers.
  • ACP security changes (semantic approval classes replacing name overrides). Need to check if my coder agent’s tool access is affected.

Don’t care but someone will:

  • QQ Bot channel, LINE media improvements, Matrix streaming, Microsoft Teams member info. Good for those platforms, not relevant to my Discord setup.
  • Slack exec approvals. Jealous, but I’m on Discord.
  • WhatsApp emoji reactions. Cool feature, wrong channel.

The Bottom Line

v2026.3.31 is the kind of release that makes the platform meaningfully better while also making the update process meaningfully riskier. The task system overhaul and security hardening are both long overdue. The breaking changes are mostly defensible. But six of them in one release, combined with 80+ individual changes, means you should not update blindly.

Read the breaking changes. Test your auth flow. Verify your node and exec approval workflows still work. Then update.

The unified task control plane alone makes this release worth the migration pain. Being able to trace a cron job through a sub-agent spawn through a blocked approval and back to the parent session is table-stakes functionality for anyone running multi-agent workflows in production. OpenClaw finally has it.

But the exec approval situation needs attention from upstream. A config setting that says “don’t ask me” should mean “don’t ask me.” Hardcoded overrides that bypass explicit operator config are a trust problem, not a security feature. Self-hosted operators who’ve already accepted the risk by setting ask: "off" shouldn’t need to patch source code to make their agent work.

Full release notes: github.com/openclaw/openclaw/releases/tag/v2026.3.31