@@ -14,6 +14,7 @@ import {
1414 formatLocationText ,
1515} from "openclaw/plugin-sdk/channel-inbound" ;
1616import { createInboundDebouncer } from "openclaw/plugin-sdk/channel-inbound-debounce" ;
17+ import { collectErrorGraphCandidates , formatErrorMessage } from "openclaw/plugin-sdk/error-runtime" ;
1718import { getChildLogger } from "openclaw/plugin-sdk/logging-core" ;
1819import {
1920 asDateTimestampMs ,
@@ -104,12 +105,31 @@ const RECONNECT_IN_PROGRESS_ERROR = "no active socket - reconnection in progress
104105const GROUP_META_TTL_MS = 5 * 60 * 1000 ;
105106const BAILEYS_MESSAGE_TTL_MS = 10 * 60 * 1000 ;
106107const INBOUND_CLOSE_DRAIN_TIMEOUT_MS = 5_000 ;
108+ const REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE = / r e p l y s e s s i o n i n i t i a l i z a t i o n c o n f l i c t e d f o r \S + / u;
107109export const WHATSAPP_GROUP_METADATA_CACHE_MAX_ENTRIES = 500 ;
108110
109111type WhatsAppGroupMetadataCacheEntry = {
110112 subject ?: string ;
111113 expires : number ;
112114} ;
115+
116+ function resolveRetryableWhatsAppInboundError (
117+ error : unknown ,
118+ ) : WhatsAppRetryableInboundError | null {
119+ if ( error instanceof WhatsAppRetryableInboundError ) {
120+ return error ;
121+ }
122+ const hasSessionInitConflict = collectErrorGraphCandidates ( error , ( current ) => [
123+ current . cause ,
124+ current . error ,
125+ ] ) . some ( ( candidate ) =>
126+ REPLY_SESSION_INIT_CONFLICT_MESSAGE_RE . test ( formatErrorMessage ( candidate ) ) ,
127+ ) ;
128+ if ( ! hasSessionInitConflict ) {
129+ return null ;
130+ }
131+ return new WhatsAppRetryableInboundError ( formatErrorMessage ( error ) , { cause : error } ) ;
132+ }
113133export type WhatsAppGroupMetadataCache = Map < string , WhatsAppGroupMetadataCacheEntry > ;
114134export type WhatsAppBaileysCacheEntry < T > = {
115135 expiresAt : number ;
@@ -465,12 +485,13 @@ export async function attachWebInboxToSocket(
465485 ( entry ) : entry is QueuedInboundMessage & { readReceipt : WhatsAppReadReceiptTarget } =>
466486 Boolean ( entry . readReceipt ) ,
467487 ) ;
468- if ( error instanceof WhatsAppRetryableInboundError ) {
469- dedupeKeys . forEach ( ( dedupeKey ) => releaseRecentInboundMessage ( dedupeKey , error ) ) ;
488+ const retryableError = resolveRetryableWhatsAppInboundError ( error ) ;
489+ if ( retryableError ) {
490+ dedupeKeys . forEach ( ( dedupeKey ) => releaseRecentInboundMessage ( dedupeKey , retryableError ) ) ;
470491 await Promise . all (
471492 durableEntries . map ( ( entry ) =>
472493 durableInboundJournal . release ( entry . durableId , {
473- lastError : formatError ( error ) ,
494+ lastError : formatError ( retryableError ) ,
474495 } ) ,
475496 ) ,
476497 ) ;
0 commit comments