toeverything/AFFiNE · error · BlockSuiteError
ErrorCode.ModelCRUDError
ErrorCode.ModelCRUDError
Error message
schema for flavour: ${this.flavour} not found What it means
Thrown by SyncController._createModel: the non-flat (classic) sync controller resolved this.flavour from the yBlock but schema.flavourSchemaMap.get(this.flavour) is undefined. Identical root cause to the flat variant (error 81) but reached through the standard SyncController path used for non-flat-data blocks.
Source
Thrown at blocksuite/framework/store/src/model/block/sync-controller.ts:133
readonly onChange?: (key: string, isLocal: boolean) => void
) {
const { id, flavour, version, yChildren, props } = this._parseYBlock();
this.id = id;
this.flavour = flavour;
this.yChildren = yChildren;
this.version = version;
this.model = this._createModel(props);
this._observeYBlockChanges();
}
private _createModel(props: UnRecord) {
const _mutex = this._mutex;
const schema = this.schema.flavourSchemaMap.get(this.flavour);
if (!schema) {
throw new BlockSuiteError(
ErrorCode.ModelCRUDError,
`schema for flavour: ${this.flavour} not found`
);
}
const model = schema.model.toModel?.() ?? new BlockModel<object>();
model.schema = schema;
const signalWithProps = Object.entries(props).reduce(
(acc, [key, value]) => {
const data = signal(value);
const dispose = effect(() => {
const value = data.value;
if (!this.model) return;
_mutex(() => {
// @ts-expect-error allow magic props
this.model.props[key] = value;
});
});View on GitHub (pinned to 26c515e050)
Solutions
- Register the missing flavour in the Schema before the SyncController is constructed.
- Verify the flavour string in 'sys:flavour' matches exactly (case-sensitive) the flavour in the block's schema definition.
- Add a migration/alias if the flavour was renamed.
- Build a startup assertion that walks the doc's flavours and fails fast with a readable list of unregistered flavours.
Example fix
// before
const schema = new Schema();
// forgot list block
const store = new Store({ schema, id });
// after
const schema = new Schema();
schema.register([ParagraphSchema, ListSchema, ...]);
const store = new Store({ schema, id }); Defensive patterns
Strategy: validation
Validate before calling
export function ensureFlavour(schema: Schema, flavour: string): void {
if (!schema.flavourSchemaMap.has(flavour)) {
throw new Error(`SyncController: flavour '${flavour}' missing from schema. Registered: ${[...schema.flavourSchemaMap.keys()].join(', ')}`);
}
}
ensureFlavour(schema, yBlock.get('sys:flavour') as string);
new SyncController(schema, yBlock, doc, onChange); Type guard
export const hasSchemaForFlavour = (schema: Schema, flavour: string): boolean => schema.flavourSchemaMap.has(flavour);
Try / catch
try {
new SyncController(schema, yBlock, doc, onChange);
} catch (e) {
if (e instanceof BlockSuiteError && e.code === ErrorCode.ModelCRUDError && /schema for flavour/.test(e.message)) {
await loadBlockPackageFor(extractFlavour(e.message));
// retry once registration settles
} else throw e;
} Prevention
- Register all block schemas before any doc opens.
- Verify flavour strings match the schema definition exactly (case-sensitive).
- Add a schema-coverage check at startup listing unregistered flavours found in the doc.
- Avoid lazy registration that races with doc open.
When it happens
Trigger: Instantiating a SyncController for a block whose 'sys:flavour' is not present in the Schema registry; common when the schema is built per-doc but the flavour list is incomplete, or a block package failed to load.
Common situations: Forgot to pass a block schema to the Doc collection's schema; dynamic import race where the doc renders before the block module finishes registering; flavour string typo or casing mismatch between data and registration; peer-supplied doc referencing an unavailable block.
Related errors
- ErrorCode.ModelCRUDError
- ErrorCode.ModelCRUDError
- ErrorCode.ModelCRUDError
- ModelCRUDError
- ReactiveProxyError
AI-assisted analysis of toeverything/AFFiNE@26c515e050 (2026-08-12).
Data as JSON: /api/errors/d4e630593996c609.
Report an issue: GitHub.