facebook/lexical · warning

console.warn(error)

Error message

console.warn(error)

What it means

defaultOnWarn is Lexical's default handler for recoverable problems routed through the editor's onWarn callback. In development (__DEV__) it throws to surface issues loudly; in production it only logs via console.warn so user-facing apps never crash on a warning.

Solutions

  1. Fix the underlying condition named by the thrown error (dev throws carry the full message).
  2. Supply onWarn in the editor config to route warnings to logging/telemetry instead of throwing: onWarn: (error) => console.error(error) or your reporter.
  3. Suppress noise in tests by installing a permissive onWarn in test editors.
  4. Only rely on prod behavior (console.warn) for end-user builds; do not treat prod warn silence as health.

Example fix

// before
const editor = createEditor({ namespace: 'app' });
// after
const editor = createEditor({
  namespace: 'app',
  onWarn: (error) => myTelemetry.warn(error.message),
});
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  runEditorOperation(editor);
} catch (e) {
  if (__DEV__ && e instanceof Error && e.message.includes('Lexical')) {
    myTelemetry.warn('Lexical dev warning thrown', e.message);
  } else { throw e; }
}

Prevention

When it happens

Trigger: An editor warning is emitted and no custom onWarn was supplied to createEditor; in dev builds this propagates the error as a thrown exception at the point of detection.

Common situations: Seeing unexpected throws in dev mode for recoverable conditions; wanting warnings collected in telemetry instead of thrown; CI runs where dev-mode throws fail tests for benign issues.


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

Appendix: source

Thrown at packages/lexical/src/LexicalEditor.ts:517

};

export type Transform<T extends LexicalNode> = (node: T) => void;

export type ErrorHandler = (error: Error) => void;

/**
 * Default {@link CreateEditorArgs.onWarn} handler. Used for recoverable,
 * warn-level conditions (e.g. the update-recursion guard tripping) that the
 * editor has already recovered from. Throws in development so the condition is
 * impossible to miss, and only `console.warn`s in production so it is not
 * reported as a fatal error. Embedders can override this via `onWarn` to route
 * the condition to their own telemetry at warn severity.
 */
function defaultOnWarn(error: Error): void {
  if (__DEV__) {
    throw error;
  }
  console.warn(error);
}

export type MutationListeners = Map<MutationListener, Set<Klass<LexicalNode>>>;

export type MutatedNodes = Map<Klass<LexicalNode>, Map<NodeKey, NodeMutation>>;

export type NodeMutation = 'created' | 'updated' | 'destroyed';

export interface MutationListenerOptions {
  /**
   * Skip the initial call of the listener with pre-existing DOM nodes.
   *
   * The default was previously true for backwards compatibility with <= 0.16.1
   * but this default has been changed to false as of 0.21.0.
   */
  skipInitialization?: boolean;
}

View on GitHub (pinned to 76a22dcba9)