From a43d8c0bdb70a2443cbb1693d1a1acf1c8e433dd Mon Sep 17 00:00:00 2001 From: adarshsm <24850536+adarshsm@users.noreply.github.com> Date: Sun, 16 Aug 2026 13:04:56 +0530 Subject: [PATCH] fix(core): don't throw when the suggestion menu opens while not editable Toggling the editor to non-editable right as the suggestion menu opens (a controlled `editable` prop can do this under load) leaves the menu view without a `state`, because it never gets shown. The stop / non-editable branch of `update()` then called `emitUpdate` unconditionally, which throws "Attempting to update uninitialized suggestions menu" (#2701). Only hide and emit when the menu actually has a `state`; if it was never shown there is nothing to update. --- .../SuggestionMenu/SuggestionMenu.test.ts | 19 +++++++++++++++++++ .../SuggestionMenu/SuggestionMenu.ts | 7 ++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.test.ts b/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.test.ts index bd1b98cb78..a1797c0299 100644 --- a/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.test.ts +++ b/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.test.ts @@ -306,4 +306,23 @@ describe("SuggestionMenu", () => { editor._tiptapEditor.destroy(); }); + + it("does not throw when the menu opens while not editable (#2701)", () => { + const editor = createEditor(); + editor.setTextCursorPosition(editor.document[0].id, "end"); + + // Toggling to non-editable right before the menu opens (as a controlled + // `editable` prop does under load) means the menu view never gets shown, so + // its `state` stays undefined. The stop/non-editable update path used to + // call `emitUpdate` unconditionally and throw. + editor.isEditable = false; + + expect(() => + editor + .getExtension(SuggestionMenu)! + .openSuggestionMenu("/", { deleteTriggerCharacter: true }), + ).not.toThrow(); + + editor._tiptapEditor.destroy(); + }); }); diff --git a/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.ts b/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.ts index 62d01c77a6..01178bb432 100644 --- a/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.ts +++ b/packages/core/src/extensions/SuggestionMenu/SuggestionMenu.ts @@ -84,10 +84,15 @@ class SuggestionMenuView { this.pluginState = stopped ? prev : next; if (stopped || !this.editor.isEditable) { + // If the menu was never actually shown (`state` is still undefined - e.g. + // it was opened while the editor was not editable, which happens when the + // editable prop is toggled right before the menu opens), there is nothing + // to hide, and calling `emitUpdate` here would throw "Attempting to update + // uninitialized suggestions menu" (#2701). if (this.state) { this.state.show = false; + this.emitUpdate(this.pluginState!.triggerCharacter); } - this.emitUpdate(this.pluginState!.triggerCharacter); return; }