openclaw - 💡(How to fix) Fix In-process subagent dispatch loses operator.write scope, breaking media-generate completion delivery

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…

Background-generated media tools (image_generate, video_generate) successfully produce files, but the completion-announce delivery back to the requester session fails with missing scope: operator.write. The agent session is never woken, so the user never receives the generated image.

Error Message

ERROR Media generation completion wake failed; requester session was not woken subsystem: agents/tools/media-generate-background-shared toolName: image_generate error: "missing scope: operator.write"

Root Cause

runAnnounceAgentCall in src/agents/subagent-announce-delivery.ts (lines ~112-124) calls dispatchGatewayMethodInProcess("agent", ...) without passing syntheticScopes:

async function runAnnounceAgentCall(params: {
  agentParams: Record<string, unknown>;
  expectFinal?: boolean;
  timeoutMs?: number;
}): Promise<unknown> {
  return await subagentAnnounceDeliveryDeps.dispatchGatewayMethodInProcess(
    "agent",
    params.agentParams,
    {
      expectFinal: params.expectFinal,
      timeoutMs: params.timeoutMs,
      // syntheticScopes missing
    },
  );
}

dispatchGatewayMethodInProcess builds a synthetic operator client via createSyntheticOperatorClient({ scopes: options?.syntheticScopes }). When syntheticScopes is undefined, the client has empty scopes. The agent method has no explicit requiredScopes, so authorizeGatewayMethod falls back to [WRITE_SCOPE] (= "operator.write") and rejects with missing scope: operator.write.

This is openclaw-internal dispatch (the system calling its own agent method to wake the requester session). The synthetic client should carry the scope the operation needs.

Fix Action

Fix / Workaround

runAnnounceAgentCall in src/agents/subagent-announce-delivery.ts (lines ~112-124) calls dispatchGatewayMethodInProcess("agent", ...) without passing syntheticScopes:

async function runAnnounceAgentCall(params: {
  agentParams: Record<string, unknown>;
  expectFinal?: boolean;
  timeoutMs?: number;
}): Promise<unknown> {
  return await subagentAnnounceDeliveryDeps.dispatchGatewayMethodInProcess(
    "agent",
    params.agentParams,
    {
      expectFinal: params.expectFinal,
      timeoutMs: params.timeoutMs,
      // syntheticScopes missing
    },
  );
}

dispatchGatewayMethodInProcess builds a synthetic operator client via createSyntheticOperatorClient({ scopes: options?.syntheticScopes }). When syntheticScopes is undefined, the client has empty scopes. The agent method has no explicit requiredScopes, so authorizeGatewayMethod falls back to [WRITE_SCOPE] (= "operator.write") and rejects with missing scope: operator.write.

Code Example

ERROR Media generation completion wake failed; requester session was not woken
     subsystem: agents/tools/media-generate-background-shared
     toolName: image_generate
     error: "missing scope: operator.write"

---

async function runAnnounceAgentCall(params: {
  agentParams: Record<string, unknown>;
  expectFinal?: boolean;
  timeoutMs?: number;
}): Promise<unknown> {
  return await subagentAnnounceDeliveryDeps.dispatchGatewayMethodInProcess(
    "agent",
    params.agentParams,
    {
      expectFinal: params.expectFinal,
      timeoutMs: params.timeoutMs,
      // syntheticScopes missing
    },
  );
}

---

async function runAnnounceAgentCall(params: {
   agentParams: Record<string, unknown>;
   expectFinal?: boolean;
   timeoutMs?: number;
 }): Promise<unknown> {
   return await subagentAnnounceDeliveryDeps.dispatchGatewayMethodInProcess(
     "agent",
     params.agentParams,
     {
       expectFinal: params.expectFinal,
       timeoutMs: params.timeoutMs,
+      syntheticScopes: ["operator.write"],
     },
   );
 }
RAW_BUFFERClick to expand / collapse

Summary

Background-generated media tools (image_generate, video_generate) successfully produce files, but the completion-announce delivery back to the requester session fails with missing scope: operator.write. The agent session is never woken, so the user never receives the generated image.

Environment

  • openclaw 2026.5.20 (installed via npm install -g openclaw)
  • macOS 15 / Node 24.6 / npm 11.5.1
  • Channels exercising this: LINE OA, but the bug is channel-agnostic (reproduces from any agent that calls image_generate)

Repro

  1. Have an agent runtime that invokes a background media tool, e.g. image_generate
  2. Wait for tool to finish producing the file
  3. Observe in gateway log:
    ERROR Media generation completion wake failed; requester session was not woken
      subsystem: agents/tools/media-generate-background-shared
      toolName: image_generate
      error: "missing scope: operator.write"
  4. Generated file IS on disk (e.g. ~/.openclaw/media/tool-image-generation/*.jpg) — only the announce-back is broken

Root cause

runAnnounceAgentCall in src/agents/subagent-announce-delivery.ts (lines ~112-124) calls dispatchGatewayMethodInProcess("agent", ...) without passing syntheticScopes:

async function runAnnounceAgentCall(params: {
  agentParams: Record<string, unknown>;
  expectFinal?: boolean;
  timeoutMs?: number;
}): Promise<unknown> {
  return await subagentAnnounceDeliveryDeps.dispatchGatewayMethodInProcess(
    "agent",
    params.agentParams,
    {
      expectFinal: params.expectFinal,
      timeoutMs: params.timeoutMs,
      // syntheticScopes missing
    },
  );
}

dispatchGatewayMethodInProcess builds a synthetic operator client via createSyntheticOperatorClient({ scopes: options?.syntheticScopes }). When syntheticScopes is undefined, the client has empty scopes. The agent method has no explicit requiredScopes, so authorizeGatewayMethod falls back to [WRITE_SCOPE] (= "operator.write") and rejects with missing scope: operator.write.

This is openclaw-internal dispatch (the system calling its own agent method to wake the requester session). The synthetic client should carry the scope the operation needs.

Suggested fix

Add syntheticScopes: ["operator.write"] to the dispatch options:

 async function runAnnounceAgentCall(params: {
   agentParams: Record<string, unknown>;
   expectFinal?: boolean;
   timeoutMs?: number;
 }): Promise<unknown> {
   return await subagentAnnounceDeliveryDeps.dispatchGatewayMethodInProcess(
     "agent",
     params.agentParams,
     {
       expectFinal: params.expectFinal,
       timeoutMs: params.timeoutMs,
+      syntheticScopes: ["operator.write"],
     },
   );
 }

Locally verified by patching the compiled bundle (dist/subagent-announce-delivery-BgV1fyQt.js) — wake delivery now succeeds and the generated image reaches the agent session as expected.

Impact

Anyone using background-dispatched media tools (image/video generation) is silently broken on completion delivery. The file is produced but never surfaces, so the user-facing symptom is "agent never replied with the image" — the actual error is buried in gateway log under Media generation completion wake failed.

Happy to open a PR if the direction is agreed.

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…

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 In-process subagent dispatch loses operator.write scope, breaking media-generate completion delivery