toeverything/AFFiNE · error · SchemaValidateError

Schema not found. The block flavour may not be registered.

Error message

Schema not found. The block flavour may not be registered.

What it means

Schema.validate(flavour, parentFlavour?, childFlavours?) throws SchemaValidateError when the flavour is absent from flavourSchemaMap, meaning no schema was ever registered for that block. Registration happens via schema.register([...]) when the Store/Collection is created from a schema array. The error means the block package providing this flavour was not imported or included in that array.

Source

Thrown at blocksuite/framework/store/src/schema/schema.ts:65

  }

  /**
   * Validates the schema relationship for a given flavour, parent, and children.
   * Throws SchemaValidateError if invalid.
   *
   * @param flavour - The block flavour to validate.
   * @param parentFlavour - The parent block flavour (optional).
   * @param childFlavours - The child block flavours (optional).
   * @throws {SchemaValidateError} If the schema relationship is invalid.
   */
  validate = (
    flavour: string,
    parentFlavour?: string,
    childFlavours?: string[]
  ): void => {
    const schema = this.flavourSchemaMap.get(flavour);
    if (!schema) {
      throw new SchemaValidateError(flavour, SCHEMA_NOT_FOUND_MESSAGE);
    }

    const validateChildren = () => {
      childFlavours?.forEach(childFlavour => {
        const childSchema = this.flavourSchemaMap.get(childFlavour);
        if (!childSchema) {
          throw new SchemaValidateError(childFlavour, SCHEMA_NOT_FOUND_MESSAGE);
        }
        this.validateSchema(childSchema, schema);
      });
    };

    if (schema.model.role === 'root') {
      if (parentFlavour) {
        throw new SchemaValidateError(
          schema.model.flavour,
          'Root block cannot have parent.'
        );

View on GitHub (pinned to b4c8548c09)

Solutions

  1. Add the missing block schema to the schema array used to create the Store/Collection (or call doc.schema.register([MissingBlock])).
  2. Import the module that registers the block before creating the store.
  3. Verify registration first: doc.schema.flavourSchemaMap.has(flavour) or doc.schema.get(flavour).
  4. Check the flavour string for typos against schema.versions, which lists every registered flavour.

Example fix

// before
const store = new Store({ id: 'doc' }); // custom block never registered
await doc.addBlock('my:custom-block', {}, parentId);

// after
import { MyCustomBlock } from './my-custom-block.js';
const store = new Store({ id: 'doc', schema: [MyCustomBlock] });
await doc.addBlock('my:custom-block', {}, parentId);
Defensive patterns

Strategy: validation

Validate before calling

if (!doc.schema.flavourSchemaMap.has(flavour)) {
  throw new Error(`flavour ${flavour} is not registered; add it to the store schema`);
}
await doc.addBlock(flavour, props, parentId);

Type guard

const isRegisteredFlavour = (schema: Schema, flavour: string): boolean =>
  schema.flavourSchemaMap.has(flavour);

Try / catch

if (!doc.schema.safeValidate(flavour, parentFlavour)) {
  // report unknown/invalid flavour without throwing
} else {
  doc.schema.validate(flavour, parentFlavour);
}

Prevention

When it happens

Trigger: doc.addBlock('affine:xyz', ...) where 'affine:xyz' was never registered; schema.validate() on a flavour string with a typo; validating a snapshot that references a block from an uninstalled package.

Common situations: Custom block defined but not added to the schema array passed to the Store; missing side-effect import of a block bundle (@blocksuite/affine blocks); flavour renamed between versions so old strings no longer resolve.

Related errors


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