facebook/lexical · error

${method} is not supported in headless mode

Error message

${method} is not supported in headless mode

What it means

createHeadlessEditor wraps a normal Lexical editor but replaces DOM-oriented methods (like focus, blur, and related methods listed in unsupportedMethods) with functions that always throw, because a headless editor has no root element or browser DOM to interact with. Headless editors are for server-side serialization, parsing, and transforms only. Calling any DOM-lifecycle method on one is a programming mistake, so the library fails fast with this message.

Source

Thrown at packages/lexical-headless/src/index.ts:36

  editorConfig?: CreateEditorArgs,
): LexicalEditor {
  const editor = createEditor(editorConfig);
  editor._headless = true;

  const unsupportedMethods = [
    'registerDecoratorListener',
    'registerRootListener',
    'registerMutationListener',
    'getRootElement',
    'setRootElement',
    'getElementByKey',
    'focus',
    'blur',
  ] as const;

  unsupportedMethods.forEach((method: (typeof unsupportedMethods)[number]) => {
    editor[method] = () => {
      throw new Error(`${method} is not supported in headless mode`);
    };
  });

  return editor;
}

View on GitHub (pinned to 76a22dcba9)

Solutions

  1. Use createEditor (browser) instead of createHeadlessEditor when you need focus/blur behavior
  2. Remove or guard focus()/blur() calls when running in headless/test environments
  3. Use environment detection to skip DOM-only setup code for headless editors

Example fix

// before
const editor = createHeadlessEditor({nodes});
editor.focus(); // throws: focus is not supported in headless mode

// after
const editor = isHeadless ? createHeadlessEditor({nodes}) : createEditor({nodes});
if (!isHeadless) editor.focus();
Defensive patterns

Strategy: try-catch

Validate before calling

function supportsDom(editor: LexicalEditor): boolean {
  return editor._rootElement !== null || !('isHeadless' in editor && editor.isHeadless);
}
// only call focus/blur when running a real (non-headless) editor

Type guard

function isHeadlessEditor(editor: LexicalEditor): boolean {
  return (editor as {_headless?: boolean})._headless === true;
}

Try / catch

try {
  editor.focus();
} catch (e) {
  if (String(e).includes('not supported in headless mode')) {
    // expected in headless/test environment; skip DOM behavior
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Invoking editor.focus(), editor.blur(), or another stubbed DOM method directly on an editor produced by createHeadlessEditor, or calling a library/plugin that internally calls those methods.

Common situations: Reusing a headless editor (built for Node/ssr tests) in browser UI code; running shared editor-setup helpers that call focus() after mount against a headless instance; SSR tests importing plugins that auto-focus.

Related errors


AI-assisted analysis of facebook/lexical@76a22dcba9 (2026-08-31). Data as JSON: /api/errors/61eae6a7f6f11d20. Report an issue: GitHub.