Summary
compat accepts Ajv's strict-mode options (strict, strictSchema, strictTypes, strictTuples, strictRequired) and declares them in compat.d.ts, but none of them appear to be enforced. Schemas that Ajv refuses to compile in strict mode compile without error.
This matters because the failure is silent rather than loud: a mistyped keyword does not raise anything, it just stops constraining. { type: 'string', maxLenght: 3 } compiles and the intended length limit is simply absent, so previously invalid data starts validating.
We hit this migrating a JSON Schema 2020-12 workload from Ajv 8.20.0. Runtime behaviour on our existing schemas is identical — we fuzzed 1,364 mutations of a real payload against both validators and found zero divergence, and the performance win is substantial. The only gap we found is authoring-time checking.
Reproduction
import Ata from 'ata-validator/compat';
const cases = {
'mistyped keyword': { type: 'object', properties: { a: { type: 'string', maxLenght: 3 } } },
'required property not defined': {
type: 'object', properties: { a: { type: 'string' } },
required: ['b'], additionalProperties: false,
},
'keyword on the wrong type': { type: 'string', minimum: 3 },
'dangling $ref': { type: 'object', properties: { a: { $ref: '#/$defs/missing' } } },
};
for (const [name, schema] of Object.entries(cases)) {
for (const opts of [{ strict: true }, { strict: 'log' }, { strictSchema: true }, { validateSchema: true }]) {
try { new Ata(opts).compile(schema); console.log(`${name} -> compiled`); }
catch (e) { console.log(`${name} -> threw: ${e.message}`); }
}
}
All 16 combinations print compiled. Ajv 8.20.0 with { strict: true } throws on all four:
| schema |
Ajv 8.20.0 |
ata-validator 1.17.2 |
maxLenght typo |
strict mode: unknown keyword: "maxLenght" |
compiled |
required: ['b'] undefined |
strict mode: required property "b" is not defined at "#" |
compiled |
minimum on a string |
strict mode: missing type "number" for keyword "minimum" |
compiled |
$ref: '#/$defs/missing' |
can't resolve reference #/$defs/nope from id # |
compiled |
Mitigating detail
A dangling $ref fails closed at validation time — the compiled function returns false for every input rather than passing everything. That is the safe direction, and worth preserving whatever else changes. The mistyped-keyword case is the one that fails open.
Environment
- ata-validator 1.17.2,
compat entry point
- Node v26.8.2, Linux
- Dialect: JSON Schema 2020-12
What would help
Any of these would resolve it for us, in rough order of preference:
- Implement the strict-mode checks behind the existing options.
- Have the constructor throw on strict options that are not yet enforced, so the gap is visible at startup rather than absent at runtime.
- Document in
compat.d.ts and the README that these options are accepted for API compatibility and currently ignored.
Happy to help test a fix. Thanks for the library — the memory and throughput numbers against our real schema were a clear improvement over Ajv.
Summary
compataccepts Ajv's strict-mode options (strict,strictSchema,strictTypes,strictTuples,strictRequired) and declares them incompat.d.ts, but none of them appear to be enforced. Schemas that Ajv refuses to compile in strict mode compile without error.This matters because the failure is silent rather than loud: a mistyped keyword does not raise anything, it just stops constraining.
{ type: 'string', maxLenght: 3 }compiles and the intended length limit is simply absent, so previously invalid data starts validating.We hit this migrating a JSON Schema 2020-12 workload from Ajv 8.20.0. Runtime behaviour on our existing schemas is identical — we fuzzed 1,364 mutations of a real payload against both validators and found zero divergence, and the performance win is substantial. The only gap we found is authoring-time checking.
Reproduction
All 16 combinations print
compiled. Ajv 8.20.0 with{ strict: true }throws on all four:maxLenghttypostrict mode: unknown keyword: "maxLenght"required: ['b']undefinedstrict mode: required property "b" is not defined at "#"minimumon a stringstrict mode: missing type "number" for keyword "minimum"$ref: '#/$defs/missing'can't resolve reference #/$defs/nope from id #Mitigating detail
A dangling
$reffails closed at validation time — the compiled function returnsfalsefor every input rather than passing everything. That is the safe direction, and worth preserving whatever else changes. The mistyped-keyword case is the one that fails open.Environment
compatentry pointWhat would help
Any of these would resolve it for us, in rough order of preference:
compat.d.tsand the README that these options are accepted for API compatibility and currently ignored.Happy to help test a fix. Thanks for the library — the memory and throughput numbers against our real schema were a clear improvement over Ajv.