Skip to content

sessions_spawn denies operator.write on BlueBubbles-driven main-agent sessions (Slack path works) #100099

Description

@iBelieveInSwordbot

2026-07-04 — sessions_spawn denies subagent runtime operator.write

Summary

On OpenClaw 2026.6.11, when a channel-driven main-agent session (e.g. agent:main:bluebubbles:direct:+1... or agent:main:slack:direct:...) calls the sessions_spawn tool to delegate a task to a subagent, the request is rejected with:

missing scope: operator.write

The main agent's runtime client identity — which the gateway synthesizes to invoke tools on behalf of the running model — appears to be missing operator.write. This blocks all subagent delegation from that surface.

Reproduction

  • OpenClaw 2026.6.11
  • Agent main running ollama/minimax-m2.5:cloud
  • Inbound channel: bluebubbles (Blue Bubbles / iMessage). Slack observed same behavior on channel-driven sessions.
  • User sends an iMessage that leads the main agent to call sessions_spawn with agentId=wozbot.

Observed behavior

The tool returns (verbatim from a runtime trajectory record at 2026-07-04T20:30:26.182Z):

{
  "toolName": "sessions_spawn",
  "meta": "Fix the FiCalc (retirement calculator) mobile touch issues ...",
  "error": "missing scope: operator.write",
  "mutatingAction": true,
  "actionFingerprint": "tool=sessions_spawn|meta=..."
}

The model receives this error, cannot delegate, and either aborts or (worse) attempts the task itself in the main-agent context — bypassing the whole point of subagent routing.

Repeats every attempt on the same session; retries do not help.

Expected behavior

The main-agent runtime should hold operator.write (and operator.read) by default. Spawning a subagent is a normal control-plane write action and should be permitted for any active agent runtime, regardless of which channel drove the inbound event.

Impact

  • All subagent delegation broken from iMessage / BlueBubbles-driven main sessions (confirmed).
  • Suspected same-shape failure on other channels — needs testing per channel.
  • Any agent config with subagents.allowAgents: [...] becomes non-functional on affected surfaces.
  • Downstream effect: models that lack strict "do not proceed without subagent" instructions will silently do the work themselves on the wrong (lower-privilege / wrong-model) main agent.

Isolation test (important)

sessions_spawn from a Slack channel-bound agent session (agent wozbot, binding agent:wozbot:slack:channel:C0AJU4X0DG9) works — subagent accepted, child ran, completion event fired normally.

sessions_spawn from a BlueBubbles channel-bound agent session (agent main, binding agent:main:bluebubbles:direct:+1...) fails with missing scope: operator.write.

Both agents are configured with subagents.allowAgents: ["wozbot", ...] and the same paired device set. The only meaningful diff is the channel plugin: BlueBubbles uses core.channel.inbound.run (which the Blue Bubbles plugin invokes from monitor-processing-*.js) → kernel.runChannelTurn. Slack uses its own inbound path that does not go through core.channel.inbound.run.

So the scope drop is on the runChannelTurn codepath (kernel-CpJ_eT7K.js) — specifically wherever the resolved turn context is handed off to the runtime that will later invoke tools on the model's behalf. The runtime identity for that path is missing operator.write.

Diagnostic breadcrumbs

  • Scope check emitter: plugin-host-hooks-BH_m3lco.js (missing scope: ${missingScope}).
  • Inbound dispatch path for BlueBubbles: inbound-reply-dispatch-DIfEV7g-.jskernel-CpJ_eT7K.js#runChannelTurndispatchResolvedChannelTurn.
  • Slack does not use this path.
  • Paired device store shows normal operator scopes for the human's CLI + Control UI devices — the missing scope is on the internal runtime identity used when the model calls a tool from a channel-driven session, not on any human-paired device.

Proposed fix: in the runChannelTurn (or dispatchResolvedChannelTurn) runtime-client construction, ensure the synthesized operator scopes include operator.write by default (or, better, use the same scope set that Slack's inbound path uses — since that path demonstrably works).

Workaround

None known short of doing coding in a dedicated wozbot-bound channel (e.g. Slack channel with a direct wozbot binding), which bypasses the main-agent spawn via the BlueBubbles path.

Environment

  • OpenClaw 2026.6.11 (e085fa1)
  • macOS Darwin 25.3.0 arm64, Node v22.22.0
  • Channels affected (confirmed): bluebubbles
  • Model provider on main: ollama/minimax-m2.5:cloud (irrelevant to the failure — the scope check happens before the tool executes)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:message-lossChannel message delivery can be lost, duplicated, or misrouted.maturity:stableIssue affects a taxonomy feature currently scored M4/M5.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions