toeverything/AFFiNE · error · Error

Invalid element type: ${yMap.get('type')}

Error message

Invalid element type: ${yMap.get('type')}

What it means

_createElementFromYMap looks up the constructor registered for a surface element's 'type' read from Yjs and throws when no such element type is registered, usually caused by deserializing data written by a newer/different build with unregistered element types.

Source

Thrown at blocksuite/framework/std/src/gfx/model/surface/surface-model.ts:247

    type: string,
    id: string,
    yMap: Y.Map<unknown>,
    options: {
      onChange: (payload: {
        id: string;
        props: Record<string, unknown>;
        oldValues: Record<string, unknown>;
        local: boolean;
      }) => void;
      skipFieldInit?: boolean;
      newCreate?: boolean;
    }
  ) {
    const stashed = new Map<string | symbol, unknown>();
    const Ctor = this._elementCtorMap[type];

    if (!Ctor) {
      throw new Error(`Invalid element type: ${yMap.get('type')}`);
    }
    const state = this._decoratorState;

    state.creating = true;
    state.skipField = options.skipFieldInit ?? false;

    let mounted = false;
    // @ts-expect-error ignore
    Ctor['_decoratorState'] = state;

    const elementModel = new Ctor({
      id,
      yMap,
      model: this,
      stashedStore: stashed,
      onChange: payload => mounted && options.onChange({ id, ...payload }),
    }) as GfxPrimitiveElementModel;

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Check the 'type' field stored in the Y.Map — it must be one of the registered surface element types (shape, text, connector, group, brush, etc.).
  2. Register the missing element type's schema/converter before deserializing the surface model.
  3. If the document was created by a newer/older version, run a migration or ignore unknown element types instead of throwing.

Example fix

const type = yMap.get('type');
if (!elementConverters[type]) {
  console.warn(`Skipping unknown surface element type: ${type}`);
  return null; // or register the converter before loading
}
Defensive patterns

Strategy: type-guard

When it happens

Trigger: Thrown at blocksuite/framework/std/src/gfx/model/surface/surface-model.ts:247 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of toeverything/AFFiNE@b4c8548c09 (2026-08-18). Data as JSON: /api/errors/d1f4b88d119ac7ba. Report an issue: GitHub.