← NEWS DESK
release impact

OpenClaw Fixes Concurrent Code Mode Tool Calls That Could Lose Side Effects or Resume the Wrong Result

A merged main-branch fix preserves real Promise settlement order, drains dispatched tools safely and keeps suspended Code Mode execution attributable.

Independent reporting and tested guidance for OpenClaw operators · Editorial standards

OpenClaw has merged a Code Mode correctness fix for concurrent and detached tools. Before the change, a script could observe the wrong Promise.race winner, lose an already dispatched side effect, report a completed call as pending, lose the original execution identity after suspension, or hang when a guest worker exited cleanly without a result.

For operators, the worst failure is not a visible exception. It is an agent run that appears complete while an audit, write or other consequential tool call was silently dropped or attributed incorrectly.

The fix landed on main at 03:45 UTC on 28 July, after 2026.7.2-beta.5 was published at 03:23 UTC. The current beta release therefore does not prove inclusion; wait for a containing package or use the exact landed source revision only if you already operate from main.

The operator decision

Workload Response
Sequential, read-only Code Mode tools No emergency action; include the fix in the normal containing-release review
Promise.race, Promise.any, detached work or nested combinators Prioritize a containing build and test completion order plus terminal state
Concurrent tools with writes, messages, approvals or audit side effects Avoid relying on the old terminal result as proof every dispatched action settled
Suspended/resumed or headless Code Mode Verify pending lists, parent execution identity, deadline and abort behaviour after upgrade
Unable to update Serialize consequential operations where possible and reconcile provider-side outcomes independently

Do not “fix” the risk by blindly retrying an uncertain run. If an old run may have dispatched a side effect, first inspect the destination or idempotency record; retrying can turn a dropped-result ambiguity into a duplicate action.

What went wrong

Code Mode executes guest JavaScript in QuickJS and bridges tool requests into OpenClaw’s tool runtime. Concurrency creates two related facts that must not be confused:

  • a JavaScript combinator may settle after one branch returns; and
  • other tool requests may already have crossed the bridge and started real work.

Native JavaScript promises do not expose a reliable ownership graph that lets the host decide every losing race branch is disposable. Cancelling or forgetting those branches can drop audits or mutations. Replaying results in request order rather than actual completion order can also identify the wrong race winner after a suspended snapshot resumes.

The merged design therefore adopts a bounded drain-all contract for requests already dispatched by the Code Mode cell. It preserves the real completion order through snapshot replay, then allows launched race branches and detached work to finish before the run becomes terminal. Existing deadline expiry and explicit abort still cancel outstanding work and release the active-run slot.

Interpretation: Promise.race still returns the first settled result to guest code, but terminal OpenClaw completion now means the bridge has accounted for every tool request the cell already launched—or a deadline/abort terminated the remainder explicitly.

What the fix changes

The pull request says the implementation now:

  • records settlement order rather than reconstructing it from launch order;
  • carries unresolved bridge requests across suspension and restore;
  • reserves and validates transferred snapshots;
  • preserves the original exec parent identity after resume;
  • removes settled calls from pending projections;
  • retains structured results from named convenience tools;
  • cleans pending work on terminal errors and aborts; and
  • fails immediately when a worker exits cleanly without returning a result.

These are lifecycle invariants, not cosmetic transcript repairs. They affect when a run can be called complete and which execution owns a tool result.

The trade-off: correctness can take longer

Draining every dispatched request means a race winner does not necessarily end the outer agent run immediately. A slow losing branch or detached tool can keep the run active until it settles, reaches the existing deadline or is explicitly aborted.

That is deliberate. Once the tool request is in flight, pretending it vanished would be faster but unsafe. Operators should nevertheless check queue occupancy and deadline settings: a correctness fix that waits for launched work can expose previously hidden slow tools.

Retain external limits for run duration, subprocess lifetime, spend and queue age. Drain-all prevents silent abandonment; it does not guarantee every launched tool is fast or well behaved.

Acceptance test for a containing build

Use disposable or idempotent fixtures and prove both result order and side-effect accounting:

  1. launch two read-only tools with deterministic different completion delays and confirm Promise.race returns the real winner;
  2. let the slower branch produce a harmless audit marker and confirm it is not dropped before terminal completion;
  3. suspend after dispatch, resume, and verify the winner plus original parent execution identity survive;
  4. exercise Promise.any, Promise.all, Promise.allSettled and nested combinations;
  5. confirm waiting/pending views contain only genuinely unfinished calls;
  6. abort with work in flight and verify cancellation is explicit and the active-run slot is released;
  7. force deadline expiry and reconcile whether any external side effect completed before cancellation; and
  8. simulate a resultless clean worker exit and confirm it fails promptly rather than hanging.

For mutating tools, use provider idempotency keys or a disposable destination. The test should not send duplicate real messages or repeatedly alter production state merely to prove concurrency.

Incident response for uncertain old runs

If a pre-fix run ended with missing, pending or contradictory tool evidence:

  1. preserve the session and run identifiers;
  2. inspect the destination system for the side effect using non-sensitive correlation data;
  3. compare tool-start, provider-acceptance and terminal records rather than trusting one transcript projection;
  4. avoid retry until you know whether the first operation committed; and
  5. if action is required, use an idempotent recovery operation or explicit human reconciliation.

This is especially important for messaging, payments, ticket changes, deployments and security-policy updates, where “result missing” is not equivalent to “operation did not happen.”

Evidence and limits

The pull request reports 371 focused Code Mode tests, interactive and headless real-worker coverage, 130,000 adversarial inputs, production build checks and direct comparison with the upstream Codex Code Mode contract. The maintainer explicitly selected drain-all semantics before merge.

OpenClaw Academy reviewed the official merged pull request and landed commit chronology. We did not independently execute QuickJS workers, suspend a real run or reproduce an external side effect. Test and runtime evidence is attributed to upstream; the reconciliation and acceptance procedure is our operator guidance.

Bottom line

Concurrent JavaScript can finish one promise while other real tools are already in flight. OpenClaw now treats those dispatched calls as work that must be accounted for before terminal completion instead of guessing that losing race branches are disposable.

Adopt a confirmed containing build if you use concurrent, detached or resumed Code Mode. Until then, serialize consequential work where practical, enforce independent run limits, and reconcile uncertain side effects before retrying.

THE RECEIPTS

Claims should survive the click.

Primary links used for this article are listed openly. If the evidence changes, the verification date changes with it.
  1. 01Preserve concurrent Code Mode tool execution — PR #114884
  2. 02Merged concurrent execution fix — commit e1ced6d

THE OPERATOR BRIEF

One useful email when the signal earns it.

Release impact, security changes and repository intelligence. No daily sludge.