Docs / EventSourcingDB / Errors / event-schema-too-complex

event-schema-too-complex

A schema is too complex to validate against: it refers back to a part of itself, or it reaches more than 10,000 subschemas.

  • Routes: register-event-schema, restore-backup, write-events, and import-events
  • Description: event schema is too complex: <reason>, with the reason it refers back to a part of itself, so validating it would not end for a schema that refers back to a part of itself or uses $dynamicRef or $recursiveRef to refer to an anchor, and it reaches more than 10000 subschemas, counting a referenced one each time it is referenced for one that reaches more; when writing events, the description starts with the place of the event in its list, counting from 0, as in /events/<index>: event schema is too complex: <reason>
  • Details: When registering a schema, none; details is an empty object. When writing events, event, the place of the event in its list, counting from 0. When restoring a backup, part, the part of the backup that holds the schema, counting from 0, with the full backup as part 0, and value, the event type of the schema. When importing events, eventId, the ID of the event whose type has the schema, and value, that event type.

Why It Happens#

Every event of a write is checked against the schema of its type before the write is stored, and the write takes as long as that check, on a core of the database, so validating against a schema has to end, and soon. A schema that refers back to a part of itself, such as one that describes a tree, whose nodes hold nodes of the same shape, could have the validation follow its references without end, so it is refused however small it is. So is a schema that uses $dynamicRef or $recursiveRef to refer to an anchor, since where such a reference leads is settled only while validating, so it cannot be checked ahead.

A schema that refers to the same definition more than once on each of many levels can be small and still take a time to validate against that doubles with every level. So a schema may reach at most 10,000 subschemas, counting a referenced one each time it is referenced, which lies far beyond what the schema of real data needs, see Limits. A schema that refers back to a part of itself is reported for that reason, whatever its size.

A schema that is not a valid JSON Schema is reported as event-schema-malformed instead, and one that does not describe an object as event-schema-not-object, since both are checked first. The schema is checked before the database is touched, so the error comes whether or not the event type has events or a schema already, and even in read-only mode. When restoring a backup, every schema of the backup is checked the same way, as it is read; the restore then fails, and the database removes what it has restored so far, see When a Restore Fails.

Writing events reports this error for an event whose type has a stored schema of either kind, which an earlier version registered, since it did not refuse such a schema. The schema stays in the store, but every write of its event type is refused with this error rather than validated, and verifying the store reports the schema. Importing events refuses the first event of that type the same way, and the import then fails, and the database removes what it has imported so far, and keeps its schemas.

How to Fix It#

Simplify the schema: describe nested data without referring back to the part that a reference lies within, for example up to a fixed depth, and refer to a definition less often, so that the schema reaches fewer subschemas. Sending the same request again fails the same way, since the error depends on the schema alone. A stored schema can be neither replaced nor removed, so for an event type whose stored schema is too complex, use a new event type instead.

Example#

To register a schema for io.eventsourcingdb.library.book-acquired whose category refers to #/$defs/category, a definition that holds its subcategories as an array of #/$defs/category again, EventSourcingDB answers with this error, as a line of the stream, and then ends the stream with its end item:

{
  "type": "error",
  "data": {
    "code": "https://docs.eventsourcingdb.io/errors/event-schema-too-complex",
    "description": "event schema is too complex: it refers back to a part of itself, so validating it would not end",
    "details": {}
  }
}