# RangeError: Adding different instances of a keyed plugin (plugin$)

**URL:** https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242
**Category:** Uncategorized
**Created:** [November 30, 2021, 9:04pm UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242 "2021-11-30T21:04:25Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [November 30, 2021, 9:04pm UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/1 "2021-11-30T21:04:25Z")

</div>

I’m loading plugins dynamically using ES6 dynamic imports. My API entry is through tiptap v2. What I’m now noticing that whenever I add the `extension-gapcursor` (which effectively is a thin layer over PMs gapcursor module) to be dynamically imported - I get an error.

This is the error:

```auto
Uncaught (in promise) RangeError: Adding different instances of a keyed plugin (plugin$)
    Configuration2 state.js:50
    Configuration2 state.js:48
    reconfigure state.js:204
    createView Editor.ts:273
    Editor Editor.ts:85
    <anonymous> main.ts:47
    promise callback* main.ts:27
    promise callback* main.ts:18
state.js:50:14

```

As a n00b this to me seems like some synthesized key somewhere (plugin$) that is somehow generated twice (is this like a pluginKey?). I tracked the origin of the plugins to:

- prosemirror-keymap and
- prosemirror-gapcursor

I do not have a clue what I can do about this. Could this be a issue in/with PM?

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [November 30, 2021, 9:28pm UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/2 "2021-11-30T21:28:35Z")

</div>

The key `plugin$` is created inside of PM - so is there any reason to think that somehow duplicate keys are being generated from within PM?

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [December 1, 2021, 7:03am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/3 "2021-12-01T07:03:01Z")

</div>

You’re somehow adding the same plugin (or two plugins with the same explicitly given `key` value) twice in your configuration. Shouldn’t be too hard to diagnose.

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 1, 2021, 7:09am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/4 "2021-12-01T07:09:43Z")

</div>

That’s the thing… I don’t 🙄

The duplicate keys are coming from: keymap and gapcursor at least that is what a debug session is revealing to me. These don’t have explicit keys.

Could this be a result of dynamic imports and promise resolution?

_edit_

When I change one of the plugin’s, synthesized keys (`plugin$`) in-flight as part of a debug session to something like `plugin$aap` everything runs fine.

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [December 1, 2021, 8:34am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/5 "2021-12-01T08:34:14Z")

</div>

Is it possible that you’re loading two instances of prosemirror-state? That might cause this (and will break other things as well).

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 1, 2021, 8:46am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/6 "2021-12-01T08:46:30Z")

</div>

Okay - sorry this might sound like a stupid question, but given that I don’t knowingly load anything that I don’t specify **how** can I find out **if** prosemirror-state is loaded twice and **what** it is that is loading it twice?

---

<div class="post-metadata">

### Author: ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)
#### Post date: [December 1, 2021, 9:21am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/7 "2021-12-01T09:21:19Z")

</div>

`npm ls prosemirror-state` will show you whether you have multiple instances installed. But even if there’s only one there, whatever loading strategy you’re using might still end up loading it twice. You could add console.log statements to the top of `node_modules/prosemirror-state/dist/*.js` and see how many of them come by in your browser console.

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 1, 2021, 9:26am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/8 "2021-12-01T09:26:43Z")

</div>

Thank you for all your insights and help, in the mean time I think I spotted some suspicious looking code in tiptap v2, which I think introduces the duplicatie `plugin$`. I don’t have a clue how to prevent this from happening and/but I’ll direct my question to them.

For the record the code is in tiptap’s ExtensionManager on a `getter` of `Plugin[]` ~ which actually augments the plugins based on the property for `addKeyboardShortcuts`

```auto
        if (addKeyboardShortcuts) {
          const bindings = Object.fromEntries(
            Object
              .entries(addKeyboardShortcuts())
              .map(([shortcut, method]) => {
                return [shortcut, () => method({ editor })]
              }),
          )

          const keyMapPlugin = keymap(bindings)

          plugins.push(keyMapPlugin)
        }

```

It is in that piece of the code that `plugins` starts storing duplicate keys.

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 1, 2021, 9:56am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/9 "2021-12-01T09:56:06Z")

</div>

@marijn - any reason why `gapCursor` does not specify a plugin key?

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 1, 2021, 10:07am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/10 "2021-12-01T10:07:51Z")

</div>

The actual duplicate `plugins` are due to:

```auto
paragraph
  - shortcut key (Mod-Alt-0) plugin, stored as plugin$
  
gapCursor
  - addProseMirrorPlugins, stored as plugin$

```

This seems beyond my control.

---

<div class="post-metadata">

### Author: ![hanspagel](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/hanspagel/32/836_2.png) [@hanspagel](https://discuss.prosemirror.net/u/hanspagel)
#### Post date: [December 1, 2021, 11:02am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/11 "2021-12-01T11:02:06Z")

</div>

Hey @pojo, don’t confuse the ProseMirror forum with all the Tiptap support channels (GitHub issues, GitHub discussions, Discord, Email). I feel bad if Tiptap users ask Marijn for help. On the one hand it’s hard for him to help with packages he doesn’t even know, and on the other hand it’s unlikely you’ll find solutions here. Please open an issue in the Tiptap repository and we’ll make sure to look into it:

> **[Build software better, together](https://github.com/ueberdosis/tiptap/issues/new/choose)**
>
> GitHub is where people build software. More than 73 million people use GitHub to discover, fork, and contribute to over 200 million projects.

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 1, 2021, 11:24am UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/12 "2021-12-01T11:24:38Z")

</div>

Sure @hanspagel

Maybe you saw that my last question was actually a PM specific one?

---

<div class="post-metadata">

### Author: ![pojo](https://discuss.prosemirror.net/letter_avatar_proxy/v4/letter/p/c68b51/32.png) [@pojo](https://discuss.prosemirror.net/u/pojo)
#### Post date: [December 2, 2021, 3:07pm UTC](https://discuss.prosemirror.net/t/rangeerror-adding-different-instances-of-a-keyed-plugin-plugin/4242/13 "2021-12-02T15:07:05Z")

</div>

In case someone is interested in the outcome of this specific issue. For my _dev_ environment I managed to resolve it through configuring vitejs appropriately (I think).

1. install prosemirror-model, prosemirror-state, prosemirror-view and prosemirror-transform
2. make the following change in vite.config.js

```auto
optimizeDeps: {
    include: [
      'prosemirror-state',
      'prosemirror-transform',
      'prosemirror-model',
      'prosemirror-view'
    ]
  }

```

The result of this are 4 separate chunks that will be loaded, which as a result makes the problem go away.
