{"record":{"id":"e3f194b1f764faeb","repo":"nanocoai/nanoclaw","slug":"post-delivery-hook-failed","errorCode":null,"errorMessage":"Post-delivery hook failed","messagePattern":"Post-delivery hook failed","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"src/delivery.ts","lineNumber":245,"sourceCode":"      if (msg.kind !== 'system' && msg.channelType !== 'agent') {\n        pauseTypingRefreshAfterDelivery(session.id);\n        if (msg.kind !== 'task_log') {\n          await fanOutboundMessage(\n            {\n              id: msg.id,\n              kind: msg.kind,\n              platform_id: msg.platformId,\n              channel_type: msg.channelType,\n              content: msg.content,\n            },\n            session,\n            agentGroup,\n          );\n          for (const hook of postDeliveryHooks) {\n            try {\n              await hook(msg, session, { firstDelivery });\n            } catch (err) {\n              log.warn('Post-delivery hook failed', { messageId: msg.id, sessionId: session.id, err });\n            }\n          }\n        }\n      }\n    } catch (err) {\n      const attempts = (deliveryAttempts.get(msg.id) ?? 0) + 1;\n      deliveryAttempts.set(msg.id, attempts);\n      if (attempts >= MAX_DELIVERY_ATTEMPTS) {\n        log.error('Message delivery failed permanently, giving up', {\n          messageId: msg.id,\n          sessionId: session.id,\n          attempts,\n          err,\n        });\n        try {\n          await withExistingMailboxSession(agentGroup.id, session.id, (mailbox) => mailbox.markDeliveryFailed(msg.id));\n          deliveryAttempts.delete(msg.id);\n        } catch (markErr) {","sourceCodeStart":227,"sourceCodeEnd":263,"githubUrl":"https://github.com/nanocoai/nanoclaw/blob/294ef2aee85218b23ad30eda9dfe10e590b54a8c/src/delivery.ts#L227-L263","documentation":"A post-delivery hook (registered to run after a message is delivered) threw. The message itself was already delivered; only follow-up side effects were skipped.","triggerScenarios":"Any postDeliveryHooks entry throwing on (msg, session, {firstDelivery}) — e.g. marking state in an external system, scheduling recurrence, or notification integrations that error.","commonSituations":"Third-party add-ons with flaky network calls; hooks written against an older message shape.","solutions":["Check the error detail to identify the hook","Fix the hook's root cause (endpoint, auth, shape)","Watch for downstream effects of the missed side effect (e.g. recurrence not scheduled) and retrigger manually"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try { await hook(msg, session, {firstDelivery}); } catch { /* delivery already done; log and move on */ }","preventionTips":["Make post-delivery hooks idempotent and fault-tolerant","Never put business-critical state exclusively in a post-delivery hook"],"tags":["delivery","hooks","side-effects"],"backgroundTag":"post-delivery-hook-failed","analyzedSha":"294ef2aee85218b23ad30eda9dfe10e590b54a8c","analyzedAt":"2026-08-28T13:59:10.357Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}