Skip to content

Fix Slack retry for session init conflicts#99647

Merged
steipete merged 3 commits into
mainfrom
fix/slack-session-init-conflict-retry
Jul 3, 2026
Merged

Fix Slack retry for session init conflicts#99647
steipete merged 3 commits into
mainfrom
fix/slack-session-init-conflict-retry

Conversation

@steipete-oai

Copy link
Copy Markdown
Contributor

Summary:

  • Treat wrapped Slack reply-session initialization conflicts as retryable inbound failures.
  • Avoid recording inbound delivery for those transient conflicts and re-enqueue the debounce flush with bounded backoff.
  • Add regression coverage for the wrapped Slack dispatch failed -> reply session initialization conflicted ... case.

Tests:

  • /home/dev-user/.local/share/crabbox-openai/openclaw/releases/fbfadbd806e16932f2c6bcaf4f283dbb1fc536f8/node_modules/.bin/oxfmt --check --threads=1 extensions/slack/src/monitor/message-handler.ts extensions/slack/src/monitor/message-handler.test.ts
  • node scripts/run-vitest.mjs run extensions/slack/src/monitor/message-handler.app-mention-race.test.ts extensions/slack/src/monitor/message-handler.test.ts
  • node scripts/run-oxlint.mjs --tsconfig config/tsconfig/oxlint.extensions.json extensions/slack/src/monitor/message-handler.ts extensions/slack/src/monitor/message-handler.test.ts

Note: the fresh PR worktree could not run pnpm install directly because the internal registry returned 403 for @openclaw/crabline; tests and lint were run using the already-installed repo dependency set from the release checkout.

@openclaw-barnacle openclaw-barnacle Bot added channel: slack Channel integration: slack size: S maintainer Maintainer-authored PR labels Jul 3, 2026
@clawsweeper

clawsweeper Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 3, 2026, 6:23 PM ET / 22:23 UTC.

Summary
The PR updates the Slack monitor message handler to treat wrapped reply-session initialization conflicts as retryable, split native retries from relay redelivery, avoid recording transient failed deliveries, and add regression tests.

PR surface: Source +70, Tests +139. Total +209 across 2 files.

Reproducibility: yes. The current-main handler path can be reproduced in the Slack message-handler harness by rejecting dispatch with a wrapped Slack dispatch failed error caused by reply session initialization conflicted ..., which current main does not classify as retryable.

Review metrics: none identified.

Merge readiness
Overall: 🦞 diamond lobster
Proof: 🌊 off-meta tidepool
Patch quality: 🦞 diamond lobster
Result: ready for maintainer review.

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

Risk before merge

  • [P1] The changed behavior is proven by focused harness tests and exact-head CI rather than a live Slack transport reproduction; maintainer review may still ask for live Slack proof before landing.

Maintainer options:

  1. Decide the mitigation before merge
    Land the focused Slack handler fix after maintainer review, preserving native retry through delivery gates and relay retry through unacknowledged redelivery.
  2. Pause or close
    Do not merge this PR until maintainers decide whether the risk is worth taking.

Next step before merge

  • [P1] No automated repair job is needed because the reviewed head has no blocking findings; the remaining action is normal maintainer and required-check handling for a maintainer-labeled Slack delivery fix.

Security
Cleared: The diff only changes Slack TypeScript runtime and tests, with no dependency, workflow, secret, package-resolution, or supply-chain surface changes.

Review details

Best possible solution:

Land the focused Slack handler fix after maintainer review, preserving native retry through delivery gates and relay retry through unacknowledged redelivery.

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

Yes. The current-main handler path can be reproduced in the Slack message-handler harness by rejecting dispatch with a wrapped Slack dispatch failed error caused by reply session initialization conflicted ..., which current main does not classify as retryable.

Is this the best way to solve the issue?

Yes. The Slack message handler is the narrow owner boundary because it owns Slack inbound delivery persistence, seen-message release, debounce retry, and relay ack behavior; the PR avoids moving Slack-specific policy into core.

AGENTS.md: found and applied where relevant.

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

Label changes

Label justifications:

  • P1: The PR addresses a Slack channel delivery retry failure where transient session initialization conflicts can prevent expected replies from completing.
  • rating: 🦞 diamond lobster: Overall readiness is 🦞 diamond lobster; proof is 🌊 off-meta tidepool and patch quality is 🦞 diamond lobster.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Not applicable: The PR is maintainer-labeled, so the external contributor real-behavior proof gate is not applied; the available proof is targeted test and CI evidence.
Evidence reviewed

PR surface:

Source +70, Tests +139. Total +209 across 2 files.

View PR surface stats
Area Files Added Removed Net
Source 1 82 12 +70
Tests 1 141 2 +139
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 2 223 14 +209

What I checked:

Likely related people:

  • vincentkoc: Commit c73e80b added SlackRetryableInboundError and explicit retry cleanup in the central Slack message-handler path. (role: introduced retry behavior; confidence: high; commits: c73e80b5a78d; files: extensions/slack/src/monitor/message-handler.ts, extensions/slack/src/monitor/message-handler.app-mention-race.test.ts)
  • steipete: Recent Slack handler history includes Peter Steinberger's Slack thread context work, and the current PR/comment thread is assigned through steipete with exact-head retry-ownership proof. (role: recent Slack area contributor and current reviewer route; confidence: high; commits: 6b525023d4d2, ac06f90c4178; files: extensions/slack/src/monitor/message-handler.ts, extensions/slack/src/monitor/message-handler.test.ts)
  • scoootscooob: PR refactor: move Slack channel implementation to extensions/ #45621 moved the Slack channel implementation into extensions/slack, the plugin boundary that owns this handler. (role: adjacent owner-boundary contributor; confidence: medium; commits: 8746362f5ebf; files: extensions/slack/src/monitor/message-handler.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.

@steipete-oai
steipete-oai force-pushed the fix/slack-session-init-conflict-retry branch from 8932462 to b34a741 Compare July 3, 2026 20:59
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. labels Jul 3, 2026
@steipete steipete self-assigned this Jul 3, 2026
@clawsweeper clawsweeper Bot added rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. labels Jul 3, 2026
@clawsweeper clawsweeper Bot removed rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 3, 2026
@steipete

steipete commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

@clawsweeper re-review

Addressed the retry-ownership finding on exact head ac06f90c4178:

  • Native Slack session-init conflicts retry through the normal persisted-delivery and seen-message gates.
  • Awaited relay deliveries do not schedule a competing local retry; failure remains unacknowledged for router redelivery.
  • Already-delivered relay replays settle without enqueueing or hanging.

Proof:

@clawsweeper

clawsweeper Bot commented Jul 3, 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.

@clawsweeper clawsweeper Bot added rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. labels Jul 3, 2026
@steipete
steipete merged commit fbdfd19 into main Jul 3, 2026
111 of 117 checks passed
@steipete
steipete deleted the fix/slack-session-init-conflict-retry branch July 3, 2026 22:45
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request Jul 4, 2026
* Fix Slack retry for session init conflicts

* fix(slack): separate native and relay retries

* style(slack): make completion exits explicit

---------

Co-authored-by: Peter Steinberger <[email protected]>
ZOOWH added a commit to ZOOWH/openclaw that referenced this pull request Jul 6, 2026
…onflict (openclaw#100944)

Port the bounded retry-with-backoff pattern from Slack (openclaw#99647) and
Telegram to Signal's debounce onFlush handler. When a follow-up Signal
DM arrives shortly after a reply completes, the session store may still
hold a stale snapshot, causing a 'reply session initialization
conflicted' error. Slack and Telegram recover by re-enqueuing the
inbound message after a short delay (up to 3 attempts).

Signal's onFlush now catches retryable errors, tracks attempts per
debounce key, and re-enqueues entries via inboundDebouncer with a 1s
delay. Non-retryable errors are still thrown to onError.
zw-xysk added a commit to zw-xysk/openclaw that referenced this pull request Jul 6, 2026
Port bounded retry-with-backoff to Signal's debounce flush path,
matching the existing Slack/Telegram behavior for the same error
class (openclaw#99647, openclaw#96550).

  - isRetryableSignalInboundError(): walks error cause chain matching
    "reply session initialization conflicted for ..."
  - flushWithRetry(): wraps handleSignalInboundMessage with up to 3
    retries at 1s intervals
  - 6 proof tests (3 fake-timer + 3 real-environment wall-clock)
  - isRetryableSignalInboundError exported for external verification

Fixes openclaw#100944
ZOOWH added a commit to ZOOWH/openclaw that referenced this pull request Jul 6, 2026
…onflict (openclaw#100944)

Port the bounded retry-with-backoff pattern from Slack (openclaw#99647) and
Telegram to Signal's debounce onFlush handler. When a follow-up Signal
DM arrives shortly after a reply completes, the session store may still
hold a stale snapshot, causing a 'reply session initialization
conflicted' error. Slack and Telegram recover by re-enqueuing the
inbound message after a short delay (up to 3 attempts).

Signal's onFlush now catches retryable errors, tracks attempts per
debounce key, and re-enqueues entries via inboundDebouncer with a 1s
delay. Non-retryable errors are still thrown to onError.
zw-xysk added a commit to zw-xysk/openclaw that referenced this pull request Jul 6, 2026
Port bounded retry-with-backoff to Signal's debounce flush path,
matching the existing Slack/Telegram behavior for the same error
class (openclaw#99647, openclaw#96550).

  - isRetryableSignalInboundError(): walks error cause chain matching
    "reply session initialization conflicted for ..."
  - flushWithRetry(): wraps handleSignalInboundMessage with up to 3
    retries at 1s intervals
  - 6 proof tests (3 fake-timer + 3 real-environment wall-clock)
  - isRetryableSignalInboundError exported for external verification

Fixes openclaw#100944
zw-xysk added a commit to zw-xysk/openclaw that referenced this pull request Jul 6, 2026
Port bounded retry-with-backoff to Signal's debounce flush path,
matching the existing Slack/Telegram behavior for the same error
class (openclaw#99647, openclaw#96550).

  - isRetryableSignalInboundError(): walks error cause chain matching
    "reply session initialization conflicted for ..."
  - flushWithRetry(): wraps handleSignalInboundMessage with up to 3
    retries at 1s intervals
  - 6 proof tests (3 fake-timer + 3 real-environment wall-clock)
  - isRetryableSignalInboundError exported for external verification

Fixes openclaw#100944
zw-xysk added a commit to zw-xysk/openclaw that referenced this pull request Jul 7, 2026
Port bounded retry-with-backoff to Signal's debounce flush path,
matching the existing Slack/Telegram behavior for the same error
class (openclaw#99647, openclaw#96550).

  - isRetryableSignalInboundError(): walks error cause chain matching
    "reply session initialization conflicted for ..."
  - flushWithRetry(): wraps handleSignalInboundMessage with up to 3
    retries at 1s intervals
  - 6 proof tests (3 fake-timer + 3 real-environment wall-clock)
  - isRetryableSignalInboundError exported for external verification

Fixes openclaw#100944
zw-xysk added a commit to zw-xysk/openclaw that referenced this pull request Jul 7, 2026
Port bounded retry-with-backoff to Signal's debounce flush path,
matching the existing Slack/Telegram behavior for the same error
class (openclaw#99647, openclaw#96550).

  - isRetryableSignalInboundError(): walks error cause chain matching
    "reply session initialization conflicted for ..."
  - flushWithRetry(): wraps handleSignalInboundMessage with up to 3
    retries at 1s intervals
  - 6 proof tests (3 fake-timer + 3 real-environment wall-clock)
  - isRetryableSignalInboundError exported for external verification

Fixes openclaw#100944
chenyangjun-xy added a commit to chenyangjun-xy/openclaw that referenced this pull request Jul 17, 2026
…ct (openclaw#108320)

When reply dispatch fails with 'reply session initialization conflicted',
the Feishu channel now retries with exponential backoff (250ms to 2s, up to
4 retries) instead of silently dropping the inbound message. Matches the
retry pattern already used by Slack (openclaw#99647) and Signal (openclaw#100944, openclaw#103218).

- Fixes off-by-one in retry/attempt counting: first attempt is outside
  the retry loop, and MAX_RETRIES = 4 consistently with the delay array
- Fixes eslint no-promise-executor-return lint error at bot.ts:121
- Adds 6 focused unit tests covering schedule, exhaustion, and shutdown
- Exports runFeishuDispatchWithSessionInitRetry for testing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: slack Channel integration: slack maintainer Maintainer-authored PR P1 High-priority user-facing bug, regression, or broken workflow. rating: 🦞 diamond lobster Very strong PR readiness with only minor maintainer review expected. size: M status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants