Schema Validation Errors
This page covers errors that occur when inserting or updating documents that violate the database schema — type mismatches, missing required fields, references to non-existent classes, or invalid enum values.
Symptoms
"api:ErrorMessage": "Schema check failure"in the response"vio:message": "Expected value of type ..."violation report- HTTP
400 Bad Requestwith a witness (violation explanation) in the body "@type": "vio:ViolationWithDatatypeObject"in the error response- Document insertion silently rejected (no error but document not persisted)
Common causes
Type mismatch on insert
Error message: "vio:message": "Expected value of type 'xsd:integer' but got 'xsd:string'"
Cause: A field value does not match the type declared in the schema. For example, passing "age": "thirty" when the schema expects "age": xsd:integer.
Fix:
- Check your schema definition for the field's expected type:
curl -u admin:root \ "http://localhost:6363/api/document/admin/mydb?graph_type=schema&type=MyClass" - Correct the value to match the declared type:Example: JSON
{ "@type": "Person", "name": "Alice", "age": 30 } - Common type pitfalls:
- Integers must be numbers, not strings:
30not"30" - Booleans must be
true/false, not"true"/"false" - Dates must be ISO 8601 format:
"2024-01-15"not"15/01/2024"
- Integers must be numbers, not strings:
Missing required fields
Error message: "vio:message": "Required field 'name' is missing"
Cause: The schema defines a field as mandatory (not Optional) but the document being inserted omits it.
Fix:
- Include all mandatory fields in your document. Check which fields are required:
curl -u admin:root \ "http://localhost:6363/api/document/admin/mydb?graph_type=schema&type=MyClass" - Fields declared as
"Optional"can be omitted; all other fields are required. - If you want a field to be optional, update the schema:Example: JSON
{ "@type": "Class", "@id": "Person", "name": "xsd:string", "nickname": { "@type": "Optional", "@class": "xsd:string" } }
Class not found
Error message: "vio:message": "Class 'Persn' not found in schema" or "@type not found"
Cause: The @type value in your document does not match any class defined in the schema. This is usually a typo or case mismatch.
Fix:
- List all classes in the schema:
curl -u admin:root \ "http://localhost:6363/api/document/admin/mydb?graph_type=schema" - Ensure the
@typematches exactly (case-sensitive):Example: JSON{ "@type": "Person", "name": "Alice" } - If you have not yet added the schema, insert it first:
curl -u admin:root -X POST \ -H "Content-Type: application/json" \ -d '{"@type": "Class", "@id": "Person", "name": "xsd:string"}' \ "http://localhost:6363/api/document/admin/mydb?graph_type=schema"
Invalid enum value
Error message: "vio:message": "Value 'active' is not a valid member of enum 'Status'"
Cause: The value supplied for an enum field is not one of the declared enum members. Enum values in TerminusDB are URIs, not plain strings.
Fix:
- Check the enum definition:
curl -u admin:root \ "http://localhost:6363/api/document/admin/mydb?graph_type=schema&id=Status" - Use the full enum value (class name +
/+ value):Example: JSON{ "@type": "Order", "status": "Status/Active" } - Not just the bare value:Example: JSON
{ "@type": "Order", "status": "Active" }
Schema check failure on replacement (incompatible migration)
Error message: "api:ErrorMessage": "Schema check failure" when replacing a schema definition via PUT, or "vio:message": "Existing data violates new schema constraint"
Cause: TerminusDB validates all existing data against the new schema. If you strengthen a constraint (e.g., making a previously Optional field mandatory, removing an enum value, or narrowing a type), existing documents that violate the new constraint cause the schema update to be rejected.
Fix:
Check what data would violate the new schema — query for documents missing the new mandatory field:
curl -u admin:root \ "http://localhost:6363/api/document/admin/MyDatabase?type=Person&query=%7B%7D" \ | jq '.[] | select(.email == null or .email == "")'Migrate data first, then tighten the schema:
- Add the field as
Optionalfirst - Backfill existing documents with valid values
- Then change the field to mandatory
- Add the field as
Use schema weakening — changes that make the schema less restrictive always succeed:
- Adding new Optional fields
- Adding new classes
- Widening a type (e.g.,
xsd:integer→xsd:decimal)
See Schema Weakening for the full rules.
For schema migrations that require both schema and data changes in one step, see Schema Migration Reference.
Circular inheritance or self-reference
Error message: "api:ErrorMessage": "Cycle detected in class hierarchy" or the schema insertion hangs/fails
Cause: A class definition uses @inherits in a way that creates a cycle — for example, Class A inherits from Class B, which inherits from Class A. TerminusDB detects inheritance cycles and rejects the schema.
Fix:
Review your class hierarchy for circular dependencies:
Example: JSON// WRONG — circular inheritance { "@type": "Class", "@id": "A", "@inherits": "B", "x": "xsd:string" } { "@type": "Class", "@id": "B", "@inherits": "A", "y": "xsd:string" }Break the cycle by extracting shared fields into an abstract base class:
Example: JSON{ "@type": "Class", "@id": "Base", "@abstract": [], "x": "xsd:string", "y": "xsd:string" } { "@type": "Class", "@id": "A", "@inherits": "Base" } { "@type": "Class", "@id": "B", "@inherits": "Base" }For property-level self-reference (a class with a field that references itself), this is NOT a cycle error — it is valid:
Example: JSON{ "@type": "Class", "@id": "TreeNode", "children": { "@type": "Set", "@class": "TreeNode" } }Self-referencing properties are fine; only inheritance cycles are prohibited.
Still stuck?
- Open an issue with your schema definition and the document you are trying to insert
- Check the Schema Reference for complete type documentation
- Check the Data Types reference for supported XSD types
- See Troubleshooting Data Model for issues with document structure and keying
- See Schema Migration Reference for safe migration strategies