OpenClaw

OpenClaw proposes automatic placement across paired session hosts

OpenClaw proposes an “any available node” dispatch path with deterministic capacity ranking and bounded failover. Two companion UI patches remove dead local-editor links for remote checkouts and make child-session load failures visible and retryable.

← Back to homeOriginal source ↗

openclaw/openclaw PR #128421 is the inspected primary source: “feat(nodes): automatic device placement for sessions.dispatch.” The related records below were inspected as supporting context rather than independent confirmation.

The facts

- openclaw/openclaw PR #128421 was created 2026-08-24T00:18:24Z and was open at inspection; its title is “feat(nodes): automatic device placement for sessions.dispatch.” - openclaw/openclaw PR #128420 was created 2026-08-24T00:18:06Z and was open at inspection; its title is “fix(ui): stop offering Open in editor for remote checkouts.” - openclaw/openclaw PR #128418 was created 2026-08-24T00:10:57Z and was open at inspection; its title is “fix(ui): show failed child-session loading and retry.” - The repository reported 387272 stars, 5981 open issues, default branch main, and last push 2026-08-24T00:37:40Z. - The latest tagged-release baseline checked was v2026.8.1-beta.2 published 2026-08-15T05:36:23Z.

What changed

openclaw/openclaw PR #128421 reports: What Problem This Solves sessions.dispatch requires an explicit {profileId} or {deviceId} target, so operators with several paired session-host nodes must hand-pick a node for every session. There is no "run this on any available node" path — the missing piece for distributing session load across a fleet of paired machines. Why This Change Was Made Adds automatic device placement: **Protocol (additive):** sessions.dispatch gains autoDevice: true, mutually exclusive with profileId/deviceId (enforced in the schema oneOf and with an actionable pre-validation message). The placement runner projection now carries the selected deviceId so callers see which node was chosen. **Selector** (src/gateway/worker-environments/device-placement-selector.ts): reuses the picker's environment catalog (no parallel discovery), filters candidates through the existing resolveDevicePlacementEligibility, ranks worker-slot runtimes by most available slots with a deterministic deviceId tie-break; remote-exec runtimes use deterministic ordering only. **Bounded failover:** at most 3 candidates; rotation happens only when the selected node fails the exact pre-provisioning eligibility fence (node churned between selection and durable provision). Authorization, provisioning, and other errors never rotate; allocated environments remain owner-bound. **Visible failure:** no eligible host fails fast stating why (none paired / all disconnected / at capacity / update required), reusing the canonical availability reasons. **Control UI:** "Any available node" option in the new-session environment picker, disabled with an actionable reason when no session hosts exist. Docs: docs/nodes/index.md, docs/web/control-ui.md, docs/gateway/protocol.md; generated protocol models

openclaw/openclaw PR #128420 reports: What Problem This Solves Fixes an issue where operators viewing their Gateway from another machine — over Tailscale, a LAN address, or a tunnel — were offered **Open in > Cursor / VS Code / Windsurf / Zed** on sessions whose files were not on their computer. Clicking it did nothing at all: no editor, no error, no toast, no recorded reason. The affordance appears on four surfaces, all affected: the sidebar/Sessions session context menu, the chat header session menu, the session file view toolbar, and the session diff file menu. Why This Change Was Made openEditor resolves to a cursor://file/ custom-scheme URL. That URL is handled by the OS behind the **browser**, while the path comes from the **Gateway's** filesystem (worktrees.list → record.path, or the session workspace root). The handoff therefore only works when the browser runs on the Gateway host — but nothing checked that. A silent action with no visible outcome is the worst bug class in this repo's Product Doctrine. Only one partial guard existed: the chat header passed row.execNode? null: workspace.root, suppressing the entry for remote exec nodes on exactly one of the four surfaces. Rather than patch four render sites, the gate lands on the **producers** of the nullable absolute path. Every surface already hides its editor affordance when that path is

openclaw/openclaw PR #128418 reports: What Problem This Solves Fixes an issue where users expanding a Control UI sidebar session would see an empty branch with no error and no way to retry when loading child sessions failed. The default main session was affected too: its children load automatically even though its parent row is intentionally hidden behind the agent identity card. Why This Change Was Made The session-data controller previously swallowed child-session request failures and retained only a private failed-key set that the sidebar could not render. Replace that set with one canonical, redacted error per parent, and share the same accessible error-and-retry presentation between visible session rows and the hidden default-main session. Preserve source/generation fencing, parent isolation, existing child rows, revision resets, and the existing direct retry path. This adds 27 production lines because a visible, accessible failure outcome and retry must exist on both the visible-parent and hidden-main rendering surfaces; the controller removes the obsolete failed-key path rather than maintaining parallel state. No public API, configuration, authentication, security, protocol, or storage behavior changes. User Impact Operators immediately see why child sessions did not load and can retry directly, including on the default main-session path. Error text is sanitized through the existing UI redaction boundary, and a failure under one parent never leaks into another session. Evidence Before: a failed request leaves an

Why it matters

The cluster turns remote session hosting from a manual target picker into an operator surface with explicit locality, capacity and failure semantics. The operator test is whether the system remains bounded and its receipts still describe the action after failure, retry or restart.

Current

The primary record was open when captured on 2026-08-24. The tagged-release baseline was v2026.8.1-beta.2 published 2026-08-15T05:36:23Z. Repository metadata, full source bodies, current pull requests and issues, releases, Google News, Hacker News, Lobsters, Metamesh and the rendered ClawCharts row were inspected. ClawCharts selected the subject; it did not prove the claim.

Evidence

The primary URL is https://github.com/openclaw/openclaw/pull/128421. Supporting records are https://github.com/openclaw/openclaw/pull/128420 and https://github.com/openclaw/openclaw/pull/128418. Source bodies, timestamps and states are preserved in the daily evidence bundle. Test counts and reproductions remain attributed to their authors unless identified as independently rerun.

Source boundary

Open work is described as open, closed work as closed, and operator reports as reports. A pull request is evidence of proposed or reviewed direction, not proof of a shipped release. Search residue, package mirrors and historically published source spines were excluded.

Operator take

Expose the selected device, rotate only on the narrow pre-provisioning eligibility fence, and never offer a local handoff when the browser cannot reach the gateway filesystem. Preserve a before-state receipt, make the smallest reversible change, and verify the original failure independently.

Caveat

Public project records are mutable. Status, scope and evidence can change after publication. This brief records the inspected state and does not authorize changes to a reader’s deployment.

Source inspected; source state, environment and release boundary remain explicit.