From 5a1b8f1b3bdda39f786115a96aa08f9f82cbdb36 Mon Sep 17 00:00:00 2001 From: Ghassan Gaidi Date: Fri, 3 Jul 2026 02:39:25 +0100 Subject: [PATCH] fix: clarify external error messages Improve error messages in conversation.external() to explicitly mention Bot API calls as the likely root cause. - wait() error: Added note that Bot API calls (ctx.api.*, ctx.reply, etc.) must not be made inside external(). - Bad replay error (state.ts): Added the actual op that was received alongside the expected op, plus a hint about the common cause. Closes #148 --- src/conversation.ts | 1 + src/state.ts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/conversation.ts b/src/conversation.ts index c9d6023..afaeab6 100644 --- a/src/conversation.ts +++ b/src/conversation.ts @@ -253,6 +253,7 @@ export class Conversation< if (this.insideExternal) { throw new Error( "Cannot wait for updates from inside `external`, or concurrently to it! \ +Bot API calls (e.g. ctx.api.*, ctx.reply) must not be made inside `external`. \ First return your data from `external` and then resume update handling using `wait` calls.", ); } diff --git a/src/state.ts b/src/state.ts index 7484c04..d9a3047 100644 --- a/src/state.ts +++ b/src/state.ts @@ -211,7 +211,11 @@ export function cursor(state: ReplayState): ReplayCursor { // replay existing data (do nothing) const expected = state.send[send].payload; if (expected !== payload) { - throw new Error(`Bad replay, expected op '${expected}'`); + throw new Error( + `Bad replay, expected op '${expected}' but got '${payload}'. \ +This usually means a Bot API call (e.g. ctx.api.*, ctx.reply) was made inside \ +\`conversation.external()\` or the conversation was otherwise used incorrectly.`, + ); } } else { // send === state.send.length // log new data