codex-team/editor.js · critical · TypeError

Constructors for abstract class Module are not allowed.

Error message

Constructors for abstract class Module are not allowed.

What it means

Module is the abstract base class all Editor.js modules extend. Its constructor guards against direct instantiation with new.target: creating a `new Module(...)` directly throws this TypeError. Only subclasses (BlockManager, Tools, etc.) may call super() through their own constructors.

Source

Thrown at src/components/__module.ts:101

      this.mutableListenerIds = [];
    },
  };

  /**
   * The set of listener identifiers which will be dropped in read-only mode
   */
  private mutableListenerIds: string[] = [];

  /**
   * @class
   * @param options - Module options
   * @param options.config - Module config
   * @param options.eventsDispatcher - Common event bus
   */
  constructor({ config, eventsDispatcher }: ModuleConfig) {
    if (new.target === Module) {
      throw new TypeError('Constructors for abstract class Module are not allowed.');
    }

    this.config = config;
    this.eventsDispatcher = eventsDispatcher;
  }

  /**
   * Editor modules setter
   *
   * @param {EditorModules} Editor - Editor's Modules
   */
  public set state(Editor: EditorModules) {
    this.Editor = Editor;
  }

  /**
   * Remove memorized nodes
   */

View on GitHub (pinned to 5f45dabbe5)

Solutions

  1. Instantiate a concrete subclass (e.g. `new BlockManager({...})`) instead of Module itself
  2. If writing a custom module, declare `class MyModule extends Module` and instantiate MyModule
  3. If using Reflect.construct, pass the subclass as the newTarget parameter: Reflect.construct(Module, args, MyModule)

Example fix

// before
const m = new Module({ config, eventsDispatcher });
// after
class MyModule extends Module {}
const m = new MyModule({ config, eventsDispatcher });
Defensive patterns

Strategy: type-guard

Validate before calling

if (Module === target || !(target.prototype instanceof Module)) { throw new TypeError('Instantiate a Module subclass'); }

Type guard

const isModuleSubclass = (C: unknown): C is typeof Module => typeof C === 'function' && C.prototype instanceof Module && C !== Module;

Try / catch

try { new Module(cfg); } catch (e) { if (e instanceof TypeError && /abstract class Module/.test(e.message)) { /* instantiate a subclass instead */ } throw e; }

Prevention

When it happens

Trigger: Calling `new Module(config)` directly in user code or in a test; a subclass whose constructor is invoked with Module as new.target (e.g. via Reflect.construct(Module, args) without a newTarget argument).

Common situations: Custom tooling/tests that try to instantiate the base class; copying module scaffolding code and forgetting to extend Module; monkey-patching or Reflect.construct usage that loses the subclass new.target.


AI-assisted analysis of codex-team/editor.js@5f45dabbe5 (2026-08-27). Data as JSON: /api/errors/0d56ea8408af07fc. Report an issue: GitHub.