openclaw - 💡(How to fix) Fix Bug: sessions_yield leaves parent session unwakeable by subagent completion events

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…

When a parent session calls sessions_yield after spawning subagents, the subagent completion event cannot independently wake the parent session. The completion result only arrives when the next user message (or heartbeat) triggers a new turn, effectively "piggybacking" on that message.

Error Message

The code then falls through to a warn log: [warn] Active requester session could not be woken for subagent completion; falling back to requester-agent handoff

Root Cause

Traced through the source code:

Fix Action

Fix / Workaround

Completion delivery path

subagent completes → deliverSubagentAnnouncement()
→ sendSubagentAnnounceDirectly()
→ checks requesterActivity.isActive via isEmbeddedPiRunActive(sessionId)
→ if active: resolveQueueEmbeddedPiMessageOutcome() to inject message into parent session
→ if not active: fallback to dispatchGatewayMethodInProcess("agent", ...) which requires external trigger

The fallback path (dispatchGatewayMethodInProcess("agent", ...)) requires an external trigger (user message, heartbeat) to execute the agent turn, which is why the completion event only arrives piggybacked on the next user message.

Code Example

subagent completes → deliverSubagentAnnouncement()
sendSubagentAnnounceDirectly()
→ checks requesterActivity.isActive via isEmbeddedPiRunActive(sessionId)
if active: resolveQueueEmbeddedPiMessageOutcome() to inject message into parent session
if not active: fallback to dispatchGatewayMethodInProcess("agent", ...) which requires external trigger

---

getRequesterSessionActivity: (requesterSessionKey) => {
    const sessionId = resolveActiveEmbeddedRunSessionId(requesterSessionKey) 
        ?? loadRequesterSessionEntry(requesterSessionKey).entry?.sessionId;
    return {
        sessionId,
        isActive: Boolean(sessionId && isEmbeddedPiRunActive(sessionId))
    };
}

---

let wakeOutcome = await resolveQueueEmbeddedPiMessageOutcome(requesterActivity.sessionId, params.triggerMessage, wakeOptions);
// wakeOutcome.queued === false

---

[warn] Active requester session could not be woken for subagent completion; falling back to requester-agent handoff
RAW_BUFFERClick to expand / collapse

Description

When a parent session calls sessions_yield after spawning subagents, the subagent completion event cannot independently wake the parent session. The completion result only arrives when the next user message (or heartbeat) triggers a new turn, effectively "piggybacking" on that message.

Reproduction

  1. In a webchat session, spawn a subagent via sessions_spawn
  2. Call sessions_yield to end the current turn
  3. Subagent completes within seconds
  4. Expected: Parent session is immediately woken with the completion event
  5. Actual: Parent session stays suspended until the user sends another message. The completion event is injected alongside the user message as <<<BEGIN_OPENCLAW_INTERNAL_CONTEXT>>>.

Observed delay: ~2 minutes in our test (subagent completed at 13:40, parent received result at 13:42 only after user sent a message).

Root Cause Analysis

Traced through the source code:

Completion delivery path

subagent completes → deliverSubagentAnnouncement()
→ sendSubagentAnnounceDirectly()
→ checks requesterActivity.isActive via isEmbeddedPiRunActive(sessionId)
→ if active: resolveQueueEmbeddedPiMessageOutcome() to inject message into parent session
→ if not active: fallback to dispatchGatewayMethodInProcess("agent", ...) which requires external trigger

The bug

In subagent-announce-delivery:

getRequesterSessionActivity: (requesterSessionKey) => {
    const sessionId = resolveActiveEmbeddedRunSessionId(requesterSessionKey) 
        ?? loadRequesterSessionEntry(requesterSessionKey).entry?.sessionId;
    return {
        sessionId,
        isActive: Boolean(sessionId && isEmbeddedPiRunActive(sessionId))
    };
}

When the parent session has called sessions_yield, isEmbeddedPiRunActive(sessionId) likely returns false because the yielded session is in a suspended/waiting state rather than an active processing state.

This causes the wake attempt to fail:

let wakeOutcome = await resolveQueueEmbeddedPiMessageOutcome(requesterActivity.sessionId, params.triggerMessage, wakeOptions);
// wakeOutcome.queued === false

The code then falls through to a warn log:

[warn] Active requester session could not be woken for subagent completion; falling back to requester-agent handoff

The fallback path (dispatchGatewayMethodInProcess("agent", ...)) requires an external trigger (user message, heartbeat) to execute the agent turn, which is why the completion event only arrives piggybacked on the next user message.

Expected Behavior

sessions_yield documentation states: "End current turn. Use after spawning subagents; results arrive as next message."

This implies subagent completion should independently trigger a new parent turn. The yielded session should be recognized as wakeable by isEmbeddedPiRunActive or a similar mechanism.

Environment

  • OpenClaw: v2026.5.20
  • Channel: webchat
  • Subagent mode: mode: "run"

Suggested Fix

isEmbeddedPiRunActive (or the activity check in getRequesterSessionActivity) should consider yielded/suspended sessions as wakeable targets. A yielded session that is waiting for subagent completions should be treated as "active enough" to receive injected messages that trigger a new turn.

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 Bug: sessions_yield leaves parent session unwakeable by subagent completion events