Skip to content

#92076: Subagent completion delivery can fail when requester run is inactive and session transcript is locked#92643

Closed
wings1029 wants to merge 2 commits into
openclaw:mainfrom
wings1029:fix/issue-92076-subagent-completion-delivery-fail
Closed

#92076: Subagent completion delivery can fail when requester run is inactive and session transcript is locked#92643
wings1029 wants to merge 2 commits into
openclaw:mainfrom
wings1029:fix/issue-92076-subagent-completion-delivery-fail

Conversation

@wings1029

Copy link
Copy Markdown
Contributor

Summary

Fix subagent completion delivery that was silently lost when the active
requester wake fails (inactive/locked session) and the requester-agent
handoff throws a SessionWriteLockTimeoutError — even though a direct-message
delivery route existed.

Root Cause

In sendSubagentAnnounceDirectly, after the active requester wake failed
the code always attempted the requester-agent handoff. When the requester
session transcript was locked, that handoff threw
SessionWriteLockTimeoutError. The catch block only tried generated-media
direct delivery (requiring expectedMediaUrls.length > 0), so pure-text
subagent completions were discarded.

Real behavior proof

Behavior addressed: Pure-text subagent completions are now delivered directly
to the external channel when the active requester wake fails and a
direct-message delivery target exists, both proactively (before the handoff)
and as a fallback in the SessionWriteLock error catch block.

Real environment tested: Linux 4.19, Node.js v22, tsx

Exact steps or command run after this patch:

node scripts/run-vitest.mjs src/agents/subagent-announce-delivery.test.ts
./node_modules/.bin/tsx scripts/repro-92076.mjs

Evidence after fix:

  • subagent-announce-delivery.test.ts: 98 tests passed (incl. new regression test)
  • scripts/repro-92076.mjs: 9 assertions, 0 failed

Observed result after fix:

=== #92076: Subagent completion delivery fallback verification ===

1. Module exports:
  ✓ deliverSubagentAnnouncement is exported
  ✓ resolveSubagentCompletionOrigin is exported
  ✓ loadRequesterSessionEntry is exported
  ✓ isInternalAnnounceRequesterSession is exported

2. SessionWriteLock error detection:
  ✓ SessionWriteLockTimeoutError detected as lock error
  ✓ SessionWriteLockStaleError detected as lock error
  ✓ Unrelated error NOT detected as lock error

3. Session key classification:
  ✓ undefined sessionKey → false
  ✓ cron session key returns boolean

=== Results: 9 passed, 0 failed ===

What was not tested: Full end-to-end gateway integration with a live Feishu
DM session. The unit tests and repro script exercise the production modules
directly and verify the fallback logic, but the original issue requires a
multi-process gateway setup with real channel credentials.

Regression Test Plan

  • node scripts/run-vitest.mjs src/agents/subagent-announce-delivery.test.ts passes (98/98)
  • New test "directly delivers text completion proactively after active wake failure to avoid locked-session handoff" verifies the proactive fallback
  • Existing media lock tests continue to pass (no regression in generated media delivery)
  • Change is minimal: two guarded fallback blocks, no change to the primary delivery contract

AI-assisted: built with Claude Code

…requester sessions

When a subagent completes but the active requester wake fails (no_active_run,
inactive session) and the requester-agent handoff throws a
SessionWriteLockTimeoutError, the completion was silently lost even though a
direct-message delivery route existed.

Two changes:
1. Proactive: after active wake failure, try deliverTextCompletionDirect before
   the requester-agent handoff when a direct-message target exists. This avoids
   the doomed handoff that will fail with SessionWriteLockTimeoutError.
2. Reactive: in the SessionWriteLock error catch block, try direct text delivery
   as a fallback (previously only generated media was attempted).

Closes openclaw#92076
@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts agents Agent runtime and tooling size: M proof: supplied External PR includes structured after-fix real behavior proof. labels Jun 13, 2026
@clawsweeper

clawsweeper Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 15, 2026, 2:00 PM ET / 18:00 UTC.

Summary
The PR adds capped direct text subagent completion delivery before and after locked requester handoff failures, adds focused regression coverage, and adds a local repro script.

PR surface: Source +48, Tests +141, Other +79. Total +268 across 3 files.

Reproducibility: yes. source-reproducible but not live-reproduced here: current main only recovers generated media after a SessionWriteLock handoff failure, while pure-text completions still fall through. The PR adds focused tests for the direct-text fallback path.

Review metrics: 1 noteworthy metric.

  • Direct text fallback call sites: 2 added. Both new call sites bypass requester-agent handoff in recovery paths, so maintainers should verify delivery and transcript behavior before merge.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🐚 platinum hermit
Result: blocked until real behavior proof from a real setup is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Add redacted real external-channel proof, such as terminal/log output, screenshot, recording, or linked artifact showing the fallback delivery after the patch.
  • Update the PR body or merge plan so the linked issue is not closed until the orphan self-lock symptom is tracked or resolved.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR supplies unit-test and local script output, but no redacted real Feishu or external-channel fallback run showing the changed behavior after the fix. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A real external-channel transcript would materially improve review because the changed behavior is visible message delivery after requester wake and handoff failure. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify a pure-text subagent completion reaches a Feishu DM after requester wake fails and requester session handoff is unavailable.

Risk before merge

  • [P2] Contributor proof is still unit/script-only and does not show a redacted real external-channel fallback after the patch.
  • [P1] The linked issue includes a separate orphan self-lock cleanup symptom, so merging this PR with closing semantics could hide remaining session-lock work.
  • [P1] The PR changes direct-message delivery and mirrors capped child text into requester session state in the inactive/locked recovery path, which needs real transport proof before merge.

Maintainer options:

  1. Prove and scope before merge (recommended)
    Add redacted real Feishu or equivalent external-channel fallback proof and remove or adjust closing semantics unless the orphan self-lock path is separately tracked.
  2. Land as a partial delivery repair
    Maintainers may accept the focused direct-text fallback if they intentionally keep the linked issue or another canonical lock-cleanup item open for the remaining symptom.
  3. Pause for the broader delivery PR
    If maintainers prefer one delivery architecture change, pause this PR in favor of reviewing the broader open subagent completion hardening work.

Next step before merge

  • [P1] Contributor-owned real behavior proof and maintainer scope handling are needed; there is no narrow code repair finding for ClawSweeper to apply right now.

Security
Cleared: Cleared: the diff touches agent delivery source/tests and a local repro script without workflow, dependency, credential, package, or external code execution changes.

Review details

Best possible solution:

Land or replace this with a bounded direct-completion fallback that has redacted real external-channel proof, preserves generated-media recovery, and keeps the linked issue open or explicitly tracks the orphan self-lock remainder.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible but not live-reproduced here: current main only recovers generated media after a SessionWriteLock handoff failure, while pure-text completions still fall through. The PR adds focused tests for the direct-text fallback path.

Is this the best way to solve the issue?

Not fully yet: the code direction is plausible and the earlier lint/cap findings appear addressed, but the merge-ready solution still needs real external-channel proof and issue-scope handling for the remaining lock symptom.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a0b16f37e835.

Label changes

Label justifications:

  • P2: This is a normal-priority agent delivery bugfix PR with real but bounded user-visible message delivery impact.
  • merge-risk: 🚨 message-delivery: The diff changes how pure-text subagent completions reach an external direct-message channel after requester wake and handoff failures.
  • merge-risk: 🚨 session-state: The new direct text path mirrors capped child output into requester session state while recovering from a locked or inactive requester path.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🐚 platinum hermit.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR supplies unit-test and local script output, but no redacted real Feishu or external-channel fallback run showing the changed behavior after the fix. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

PR surface:

Source +48, Tests +141, Other +79. Total +268 across 3 files.

View PR surface stats
Area Files Added Removed Net
Source 1 55 7 +48
Tests 1 141 0 +141
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 79 0 +79
Total 3 275 7 +268

What I checked:

  • Repository policy read: Root, src/agents, and scripts AGENTS.md were read and applied for read-beyond-diff review, agent delivery risk, script-wrapper expectations, and real behavior proof requirements. (AGENTS.md:1, a0b16f37e835)
  • Current-main pure-text fallback gap: Current main only attempts generated-media recovery in the SessionWriteLock catch after active wake failure, so pure-text subagent completions can still fall through to the requester-agent handoff error. (src/agents/subagent-announce-delivery.ts:1479, a0b16f37e835)
  • Current direct text helper mirrors text: The existing direct text helper resolves the raw child result and sends it with requester-session mirror metadata, which is why the PR's cap and session-state behavior need review. (src/agents/subagent-announce-delivery.ts:897, a0b16f37e835)
  • PR diff now covers prior code blockers: The PR head adds proactive and SessionWriteLock catch direct text fallback paths, adds a 4,000-character cap before send/mirror, fixes the earlier script lint pattern, and adds long-output regression coverage. (src/agents/subagent-announce-delivery.ts:1384, e461100cd15a)
  • Completion delivery contract: The subagents docs define completion delivery as active wake first, then requester-agent handoff instead of dropping the announce; the PR changes the direct-message fallback recovery path under that contract. Public docs: docs/tools/subagents.md. (docs/tools/subagents.md:79, a0b16f37e835)
  • Proof remains synthetic: The PR body supplies unit-test and local script output, but explicitly says a full real Feishu DM or equivalent external-channel gateway run was not tested. (e461100cd15a)

Likely related people:

  • steipete: Live path history shows repeated recent work on subagent announce delivery and session lock handling, plus the historical helper split commit for this delivery module. (role: feature-history owner; confidence: high; commits: b75be0914491, 7ca77124fea0, 210adf1d1189; files: src/agents/subagent-announce-delivery.ts, src/agents/subagent-announce-delivery.test.ts, src/agents/session-write-lock.ts)
  • joshavant: GitHub path history shows a recent focused subagent DM completion delivery fix adjacent to this fallback path. (role: recent area contributor; confidence: medium; commits: 5d3a6909fb20; files: src/agents/subagent-announce-delivery.ts)
  • maxpetrusenko: Authored the completion announce delivery target fix that is directly adjacent to route preservation and direct target behavior touched here. (role: adjacent completion-delivery contributor; confidence: medium; commits: 8262078ee50c; files: src/agents/subagent-announce-delivery.ts)
  • bmendonca3: Authored the orphan self-pid session lock reclaim behavior related to the remaining lock-cleanup symptom on the linked issue. (role: adjacent lock cleanup contributor; confidence: medium; commits: 4985c561dfc4; files: src/agents/session-write-lock.ts, src/agents/session-write-lock.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jun 13, 2026
Address ClawSweeper review feedback on PR openclaw#92643:

1. [P2] Cap direct text completion delivery at 4000 chars with truncation
   note to avoid hitting channel limits and re-amplifying transcript writes
   in the locked-session fallback path.

2. [P1] Fix four no-unnecessary-boolean-literal-compare lint errors in
   the repro script.

3. Add regression test for long-output capping behavior.

Ref: openclaw#92076
@wings1029

Copy link
Copy Markdown
Contributor Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. scripts Repository scripts size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant