Found while bringing a dev instance up to development. The OpenRegister UI was entirely blank because /apps/openregister/api/dashboard returned 500:
Failed to get registers with schemas:
Schema '1119': Property 'orderDate' cannot change format from 'date-time' to 'date'
What is actually happening
Three schemas, owned by two different apps, all declare "x-schema-org": "schema:Order":
| id |
slug |
app |
orderDate format |
| 1119 |
SalesOrder |
shillinq |
date |
| 5049 |
OrderPrimitive |
shillinq |
date-time |
| 1585 |
order |
decidesk |
date-time |
SchemaMapper::validateFormatConstraint() treats the shared marker as an inheritance relationship and refuses the format difference — so decidesk's schema was acting as the parent of shillinq's, and shillinq's own declared format (date, with date-only sample data in its register config) was rejected.
Neither app declares the other. They only have a schema.org marker in common.
Two defects, not one
1. A schema.org marker is not an inheritance edge. schema:Order says "this represents a schema.org Order" — it is a semantic annotation, not a statement that two apps' schemas must agree on every property's format. Treating it as inheritance means any app can constrain any other app's schema by coincidence of annotation. This is the same class of cross-app collision as the slug bug fixed in #2047, on a different key.
2. One bad schema takes down the entire dashboard. getRegistersWithSchemas() throws, so a single inheritance conflict blanks the whole app for every register and every user. That should degrade — skip the offending schema, surface it as a warning in the response — rather than 500.
Defect 2 is arguably the more urgent: it turns any future schema disagreement anywhere in the fleet into a total outage of the OpenRegister UI.
Workaround applied on the dev instance
Set orderDate.format to date on schemas 5049 and 1585 so the three agree. Both had 0 objects, so no data was affected. That unblocks the instance but does not fix either defect — the next marker collision reproduces it.
Suggested fix
- Scope inheritance validation to schemas within the same application (or to an explicit
extends/implements relationship the author declared), not to a shared x-schema-org value.
- Make
getRegistersWithSchemas() resilient: collect per-schema validation errors and return them alongside the working registers instead of throwing.
Found while bringing a dev instance up to
development. The OpenRegister UI was entirely blank because/apps/openregister/api/dashboardreturned 500:What is actually happening
Three schemas, owned by two different apps, all declare
"x-schema-org": "schema:Order":orderDateformatdatedate-timedate-timeSchemaMapper::validateFormatConstraint()treats the shared marker as an inheritance relationship and refuses the format difference — so decidesk's schema was acting as the parent of shillinq's, and shillinq's own declared format (date, with date-only sample data in its register config) was rejected.Neither app declares the other. They only have a schema.org marker in common.
Two defects, not one
1. A schema.org marker is not an inheritance edge.
schema:Ordersays "this represents a schema.org Order" — it is a semantic annotation, not a statement that two apps' schemas must agree on every property's format. Treating it as inheritance means any app can constrain any other app's schema by coincidence of annotation. This is the same class of cross-app collision as the slug bug fixed in #2047, on a different key.2. One bad schema takes down the entire dashboard.
getRegistersWithSchemas()throws, so a single inheritance conflict blanks the whole app for every register and every user. That should degrade — skip the offending schema, surface it as a warning in the response — rather than 500.Defect 2 is arguably the more urgent: it turns any future schema disagreement anywhere in the fleet into a total outage of the OpenRegister UI.
Workaround applied on the dev instance
Set
orderDate.formattodateon schemas 5049 and 1585 so the three agree. Both had 0 objects, so no data was affected. That unblocks the instance but does not fix either defect — the next marker collision reproduces it.Suggested fix
extends/implementsrelationship the author declared), not to a sharedx-schema-orgvalue.getRegistersWithSchemas()resilient: collect per-schema validation errors and return them alongside the working registers instead of throwing.