openclaw - 💡(How to fix) Fix bug: subagent announce direct-send error silently swallowed when queue fallback recovers [1 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#62968Fetched 2026-04-09 07:59:59
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
cross-referenced ×3

Error Message

// ~line 512 } catch (err) { return { delivered: false, path: "direct", error: summarizeDeliveryError(err), }; }

Fix Action

Fix / Workaround

When sendSubagentAnnounceDirectly fails but the queue fallback succeeds in runSubagentAnnounceDispatch, the direct-send error is silently swallowed — never logged.

src/agents/subagent-announce-dispatch.tsrunSubagentAnnounceDispatch records the direct failure as a phase, but when queue fallback succeeds it returns the queue result:

  1. Inside runSubagentAnnounceDispatch when direct fails before attempting queue fallback
  2. In the caller by inspecting delivery.phases for failed direct-primary phases

Code Example

// ~line 512
} catch (err) {
    return {
      delivered: false,
      path: "direct",
      error: summarizeDeliveryError(err),
    };
  }

---

const primaryDirect = await params.direct();
appendPhase("direct-primary", primaryDirect);  // error recorded here...
if (primaryDirect.delivered) {
    return withPhases(primaryDirect);
}
// ...
const fallbackQueue = mapQueueOutcomeToDeliveryResult(fallbackQueueOutcome);
appendPhase("queue-fallback", fallbackQueue);
if (fallbackQueue.delivered) {
    return withPhases(fallbackQueue);  // ...but top-level result is "queued", delivered=true
}

---

// ~line 621
if (!delivery.delivered && delivery.path === "direct" && delivery.error) {
    defaultRuntime.error?.(...);
}
RAW_BUFFERClick to expand / collapse

Problem

When sendSubagentAnnounceDirectly fails but the queue fallback succeeds in runSubagentAnnounceDispatch, the direct-send error is silently swallowed — never logged.

Code path

src/agents/subagent-announce-delivery.tssendSubagentAnnounceDirectly catches errors and returns them in the result without logging:

// ~line 512
} catch (err) {
    return {
      delivered: false,
      path: "direct",
      error: summarizeDeliveryError(err),
    };
  }

src/agents/subagent-announce-dispatch.tsrunSubagentAnnounceDispatch records the direct failure as a phase, but when queue fallback succeeds it returns the queue result:

const primaryDirect = await params.direct();
appendPhase("direct-primary", primaryDirect);  // error recorded here...
if (primaryDirect.delivered) {
    return withPhases(primaryDirect);
}
// ...
const fallbackQueue = mapQueueOutcomeToDeliveryResult(fallbackQueueOutcome);
appendPhase("queue-fallback", fallbackQueue);
if (fallbackQueue.delivered) {
    return withPhases(fallbackQueue);  // ...but top-level result is "queued", delivered=true
}

src/agents/subagent-announce.ts — the caller only logs when overall delivery failed:

// ~line 621
if (!delivery.delivered && delivery.path === "direct" && delivery.error) {
    defaultRuntime.error?.(...);
}

When queue recovers: delivered=true, path="queued" → condition is false → error lost.

Observation

The phases array does capture the direct-send failure, but nothing inspects it for logging. The diagnostic information exists in the return value but is never surfaced.

Impact

  • Cron jobs with expectsCompletionMessage: true that hit transient direct-send failures (after retry exhaustion) silently fall back to queue delivery with no diagnostic trace.
  • Operators cannot distinguish "direct send worked" from "direct send failed, queue recovered" in logs.

Suggested fix

Log the direct-send error at warn level when falling back to queue — either:

  1. Inside runSubagentAnnounceDispatch when direct fails before attempting queue fallback
  2. In the caller by inspecting delivery.phases for failed direct-primary phases

Option 1 is simpler and keeps the logging close to the decision point.

extent analysis

TL;DR

Log the direct-send error at warn level when falling back to queue delivery to prevent silent failures.

Guidance

  • Modify runSubagentAnnounceDispatch to log the direct-send error when it fails and before attempting queue fallback.
  • Alternatively, update the caller to inspect delivery.phases for failed direct-primary phases and log the error.
  • Consider adding a check for delivery.path === "queued" and delivery.phases containing a failed direct-primary phase to log the error in the caller.
  • Review the logging level to ensure it is set to warn or a suitable level to alert operators of transient direct-send failures.

Example

// Inside runSubagentAnnounceDispatch
if (!primaryDirect.delivered) {
  defaultRuntime.warn(`Direct send failed: ${primaryDirect.error}`);
}

Notes

The suggested fix requires modifying either runSubagentAnnounceDispatch or the caller to log the direct-send error. The choice between the two options depends on the desired logging behavior and the complexity of the code changes.

Recommendation

Apply workaround: Log the direct-send error at warn level when falling back to queue delivery, as it provides a clear and simple solution to the problem of silent failures.

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