openclaw - 💡(How to fix) Fix [Bug]: sessions_spawn fails with missing scope operator.write despite full-scope operator token [2 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#77807Fetched 2026-05-06 06:21:03
View on GitHub
Comments
2
Participants
2
Timeline
2
Reactions
2
Author
Timeline (top)
commented ×2

sessions_spawn fails on OpenClaw 2026.5.4 with:

missing scope: operator.write

even after the local operator device token and paired-device state have been rotated/synced to include the full operator scope set.

A direct Gateway agent RPC using the same operator device token and the same full scopes succeeds, so the failure appears specific to the sessions_spawn -> spawnSubagentDirect -> callGateway(method="agent") path.

This looks related to earlier pairing required / scope-upgrade reports for internal gateway-client self-calls, but the current observable failure is missing scope: operator.write even when the stored token scopes are already correct.

Error Message

GatewayClientRequestError: device token rotation denied

Root Cause

From source inspection, this appears to happen because the CLI method call for device.token.rotate connects with the least-privilege method scope (operator.pairing), while rotating a token that includes operator.admin / operator.write / operator.approvals requires the caller connection itself to hold those scopes.

Code Example

missing scope: operator.write

---

operator.admin
operator.approvals
operator.pairing
operator.read
operator.write
operator.talk.secrets

---

{
  "runtime": "subagent",
  "mode": "run",
  "label": "subagent-smoke-test",
  "task": "Smoke test. Reply briefly. Do not use tools.",
  "timeoutSeconds": 120,
  "runTimeoutSeconds": 120
}

---

{
  "status": "error",
  "error": "missing scope: operator.write",
  "childSessionKey": "<redacted>",
  "runId": "<redacted>"
}

---

operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write

---

GatewayClientRequestError: device token rotation denied

---

missing scope: operator.write

---

{
  "ok": true,
  "runId": "<redacted>"
}
RAW_BUFFERClick to expand / collapse

Summary

sessions_spawn fails on OpenClaw 2026.5.4 with:

missing scope: operator.write

even after the local operator device token and paired-device state have been rotated/synced to include the full operator scope set.

A direct Gateway agent RPC using the same operator device token and the same full scopes succeeds, so the failure appears specific to the sessions_spawn -> spawnSubagentDirect -> callGateway(method="agent") path.

This looks related to earlier pairing required / scope-upgrade reports for internal gateway-client self-calls, but the current observable failure is missing scope: operator.write even when the stored token scopes are already correct.

Environment

  • OpenClaw: 2026.5.4 (325df3e)
  • OS: Linux x64
  • Node: v22.22.2
  • Gateway: local Gateway, token auth enabled
  • Agent session: main agent session, sessions_spawn tool available
  • Runtime/model details do not appear relevant; failure happens before the child agent turn starts

Related issues

Possibly related, but not identical:

  • #21655 — Internal gateway operations (cron, announce, sessions_spawn) fail due to device scope enforcement on self-calls
  • #23160 — Sub-agent spawn fails with pairing required after update
  • #23187 — Sub-agent sessions_spawn fails with pairing required
  • #23661 — Subagent sessions fail with pairing required on loopback gateway
  • #70687 — Scope upgrade pending approval after upgrade

The difference here is that the stored operator device token already has operator.write, and a direct agent RPC succeeds with that token, while the built-in sessions_spawn tool still fails.

Steps to reproduce

  1. Run OpenClaw 2026.5.4 with a local Gateway using token auth.
  2. Ensure sessions_spawn is available in the main agent session.
  3. Confirm the paired operator device and local device-auth token include full scopes:
operator.admin
operator.approvals
operator.pairing
operator.read
operator.write
operator.talk.secrets
  1. Call sessions_spawn from the main agent session with a minimal native subagent task:
{
  "runtime": "subagent",
  "mode": "run",
  "label": "subagent-smoke-test",
  "task": "Smoke test. Reply briefly. Do not use tools.",
  "timeoutSeconds": 120,
  "runTimeoutSeconds": 120
}

Actual behavior

sessions_spawn returns an error:

{
  "status": "error",
  "error": "missing scope: operator.write",
  "childSessionKey": "<redacted>",
  "runId": "<redacted>"
}

The child session key/run id are created, but the child run does not start successfully.

Expected behavior

sessions_spawn should start the subagent run when the local operator token has operator.write, or the internal Gateway call should use an auth path/scopes that satisfy the agent RPC requirement.

Diagnostics performed

1. Verified stored operator scopes

Both the paired-device state and the local operator device-auth token contain the full scope set:

operator.admin, operator.approvals, operator.pairing, operator.read, operator.talk.secrets, operator.write

The paired token and local cached token were also verified to be identical after manual rotation/sync.

No token, device id, user id, IP, or account/channel identifier is included here.

2. openclaw devices rotate via CLI was denied

Running the documented rotate command with full scopes was denied:

GatewayClientRequestError: device token rotation denied

From source inspection, this appears to happen because the CLI method call for device.token.rotate connects with the least-privilege method scope (operator.pairing), while rotating a token that includes operator.admin / operator.write / operator.approvals requires the caller connection itself to hold those scopes.

3. Direct full-scope WS device.token.rotate succeeded

Using a direct Gateway WebSocket client with the existing operator device token and explicit full scopes, device.token.rotate succeeded and returned a new full-scope operator token.

The local device-auth cache was then synced to the newly rotated token and verified against the paired-device state.

4. sessions_spawn still failed after successful rotation/sync

After rotation and local cache sync, the same sessions_spawn smoke test still returned:

missing scope: operator.write

5. Direct Gateway agent RPC succeeds with same token/scopes

As a control test, a direct Gateway WebSocket client was created using the same operator device token and the same full scope list, then called the agent RPC directly with a minimal message and a fresh session key.

That direct agent call succeeded and returned a run id:

{
  "ok": true,
  "runId": "<redacted>"
}

This strongly suggests the Gateway agent RPC and the operator token are valid, and the failure is in the built-in sessions_spawn path rather than in Gateway auth generally.

Source-level hypothesis

From the installed build:

  • sessions_spawn calls spawnSubagentDirect(...)
  • spawnSubagentDirect(...) eventually calls callSubagentGateway({ method: "agent", ... })
  • agent is classified as requiring operator.write
  • callGateway(...) defaults to backend gateway-client behavior and least-privilege/shared-auth handling unless explicit scopes/device auth are supplied

The observed behavior is consistent with the internal callGateway(method="agent") path connecting without an effective operator.write scope, even though the local operator device token has it.

In this environment, direct WS with explicit device token + full scopes works; built-in sessions_spawn does not.

Impact

High for multi-agent workflows: native subagent delegation is blocked even though the operator token and Gateway are otherwise functional.

This prevents using subagents for task decomposition, review, and execution isolation.

Privacy note

All device IDs, session keys, run IDs, IP addresses, tokens, token hashes, user/account IDs, and channel identifiers have been redacted or omitted intentionally.

extent analysis

TL;DR

The most likely fix is to modify the callGateway function in spawnSubagentDirect to use the full scope list from the local operator device token.

Guidance

  1. Verify the scope handling: Check how the callGateway function handles scopes, specifically for the agent method, to ensure it's using the correct scopes from the local operator device token.
  2. Modify the callGateway function: Update the callGateway function to explicitly pass the full scope list from the local operator device token when calling the agent method.
  3. Test with explicit scopes: Test the sessions_spawn function with explicit scopes to confirm that it works as expected.
  4. Review related issues: Review the related issues (#21655, #23160, #23187, #23661, #70687) to ensure that the fix doesn't introduce any regressions.

Example

// Example of how to modify the callGateway function to use the full scope list
const fullScopes = ['operator.admin', 'operator.approvals', 'operator.pairing', 'operator.read', 'operator.write', 'operator.talk.secrets'];
callGateway({ method: 'agent', scopes: fullScopes, ... });

Notes

The fix may require changes to the gateway-client behavior and shared-auth handling to ensure that the correct scopes are used when calling the agent method.

Recommendation

Apply a workaround by modifying the callGateway function to use the full scope list from the local operator device token, as this is the most direct way to address the issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

sessions_spawn should start the subagent run when the local operator token has operator.write, or the internal Gateway call should use an auth path/scopes that satisfy the agent RPC requirement.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: sessions_spawn fails with missing scope operator.write despite full-scope operator token [2 comments, 2 participants]