Bug Description
XGtsRefValidator::visit_instance() only recurses into properties (for objects) and items (for arrays), but does not traverse into JSON Schema combinators (oneOf, anyOf, allOf). This means x-gts-ref constraints nested inside these combinators are silently ignored during instance validation.
Additionally, remove_x_gts_ref_fields() in store.rs strips all x-gts-ref fields before passing the schema to the jsonschema crate. Subschemas containing only x-gts-ref become empty schemas {}. When placed inside oneOf, both empty subschemas match any value, causing oneOf to always fail (it requires exactly 1 match out of N).
The combined effect: x-gts-ref inside oneOf/anyOf/allOf is broken at both validation layers.
This is the same issue as GlobalTypeSystem/gts-ts#10 in the TypeScript adapter.
Root Cause
In gts/src/x_gts_ref.rs, visit_instance() (lines ~165-220) handles:
- ✅
schema.properties — recurses into object properties
- ✅
schema.items — recurses into array items
- ❌
schema.oneOf — not traversed
- ❌
schema.anyOf — not traversed
- ❌
schema.allOf — not traversed
Note that visit_schema() does correctly handle combinators because it generically iterates over all keys. The inconsistency is only in visit_instance().
Reproduction
Schema (action.v1.json)
{
"$id": "gts://gts.hai3.mfes.comm.action.v1~",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"type": {
"x-gts-ref": "/$id"
},
"target": {
"type": "string",
"oneOf": [
{ "x-gts-ref": "gts.hai3.mfes.ext.domain.v1~*" },
{ "x-gts-ref": "gts.hai3.mfes.ext.extension.v1~*" }
]
}
},
"required": ["type", "target"]
}
Instance (valid action targeting a domain)
{
"type": "gts.hai3.mfes.comm.action.v1~hai3.mfes.ext.mount_ext.v1",
"target": "gts.hai3.mfes.ext.domain.v1~hai3.screensets.layout.screen.v1"
}
Expected behavior
Validation passes — target matches the first x-gts-ref pattern (gts.hai3.mfes.ext.domain.v1~*).
Actual behavior
Validation fails. The jsonschema crate sees both oneOf subschemas as {} (since x-gts-ref was stripped), both match the string value, and oneOf fails because 2 subschemas matched instead of 1. Meanwhile, visit_instance() never sees the x-gts-ref constraints at all because it does not recurse into oneOf branches.
Suggested Fix
visit_instance() should recurse into combinator subschemas:
// After handling properties and items:
for combinator in &["oneOf", "anyOf", "allOf"] {
if let Some(Value::Array(sub_schemas)) = sch_obj.get(*combinator) {
for sub_schema in sub_schemas {
self.visit_instance(inst, sub_schema, root_schema, path, errors);
}
}
}
For oneOf semantics specifically, the validator should check that the instance matches exactly one x-gts-ref pattern among the subschemas (mirroring JSON Schema oneOf semantics).
Impact
This bug blocks any schema that uses x-gts-ref inside JSON Schema combinators. The workaround is to flatten x-gts-ref to the property level (e.g., using a broader wildcard pattern), but this loses the ability to express "target must be one of these specific type families."
Bug Description
XGtsRefValidator::visit_instance()only recurses intoproperties(for objects) anditems(for arrays), but does not traverse into JSON Schema combinators (oneOf,anyOf,allOf). This meansx-gts-refconstraints nested inside these combinators are silently ignored during instance validation.Additionally,
remove_x_gts_ref_fields()instore.rsstrips allx-gts-reffields before passing the schema to thejsonschemacrate. Subschemas containing onlyx-gts-refbecome empty schemas{}. When placed insideoneOf, both empty subschemas match any value, causingoneOfto always fail (it requires exactly 1 match out of N).The combined effect:
x-gts-refinsideoneOf/anyOf/allOfis broken at both validation layers.This is the same issue as GlobalTypeSystem/gts-ts#10 in the TypeScript adapter.
Root Cause
In
gts/src/x_gts_ref.rs,visit_instance()(lines ~165-220) handles:schema.properties— recurses into object propertiesschema.items— recurses into array itemsschema.oneOf— not traversedschema.anyOf— not traversedschema.allOf— not traversedNote that
visit_schema()does correctly handle combinators because it generically iterates over all keys. The inconsistency is only invisit_instance().Reproduction
Schema (
action.v1.json){ "$id": "gts://gts.hai3.mfes.comm.action.v1~", "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object", "properties": { "type": { "x-gts-ref": "/$id" }, "target": { "type": "string", "oneOf": [ { "x-gts-ref": "gts.hai3.mfes.ext.domain.v1~*" }, { "x-gts-ref": "gts.hai3.mfes.ext.extension.v1~*" } ] } }, "required": ["type", "target"] }Instance (valid action targeting a domain)
{ "type": "gts.hai3.mfes.comm.action.v1~hai3.mfes.ext.mount_ext.v1", "target": "gts.hai3.mfes.ext.domain.v1~hai3.screensets.layout.screen.v1" }Expected behavior
Validation passes —
targetmatches the firstx-gts-refpattern (gts.hai3.mfes.ext.domain.v1~*).Actual behavior
Validation fails. The
jsonschemacrate sees bothoneOfsubschemas as{}(sincex-gts-refwas stripped), both match the string value, andoneOffails because 2 subschemas matched instead of 1. Meanwhile,visit_instance()never sees thex-gts-refconstraints at all because it does not recurse intooneOfbranches.Suggested Fix
visit_instance()should recurse into combinator subschemas:For
oneOfsemantics specifically, the validator should check that the instance matches exactly onex-gts-refpattern among the subschemas (mirroring JSON SchemaoneOfsemantics).Impact
This bug blocks any schema that uses
x-gts-refinside JSON Schema combinators. The workaround is to flattenx-gts-refto the property level (e.g., using a broader wildcard pattern), but this loses the ability to express "target must be one of these specific type families."