ajv icon indicating copy to clipboard operation
ajv copied to clipboard

strictTuples warning when using 2020-12 draft prefixItems with optional

Open KuSh opened this issue 1 year ago • 2 comments

What version of Ajv are you using? Does the issue happen if you use the latest version? I'm using latest Ajv version as of now (8.12.0)

Ajv options object

const options = { allErrors: true };

JSON Schema

{
  "$id": "https://www.example.com/schemas/test",
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "description": "A schema for unit testing",
  "type": "object",
  "properties": {
    "foo": {
      "type": "string",
      "minLength": 2
    },
    "bar": {
      "type": "number",
      "minimum": 0
    },
    "baz": {
      "type": "array",
      "items": { "type": "string" },
      "minItems": 2,
      "prefixItems": [{ "const": "test" }]
    }
  },
  "required": ["foo", "baz"]
}

Sample data

{
  "foo": "foo",
  "bar": 1,
  "baz": ["test", "ok"]
}

Your code

import Ajv from 'ajv/dist/2020';
const ajv = new Ajv();
const validate = ajv.compile(schema);
const valid = validate(data); // warn: strict mode: "prefixItems" is 2-tuple, but minItems or maxItems/items are not specified or different at path "#/properties/baz"

Validation result, data AFTER validation, error messages

{
  errors: null,
  schema: {
    '$id': 'https://www.example.com/schemas/test',
    '$schema': 'https://json-schema.org/draft/2020-12/schema',
    description: 'A schema for unit testing',
    type: 'object',
    properties: { foo: [Object], bar: [Object], baz: [Object] },
    required: [ 'foo', 'baz' ]
  },
  schemaEnv: <ref *1> SchemaEnv {
    refs: {},
    dynamicAnchors: {},
    schema: {
      '$id': 'https://www.example.com/schemas/test',
      '$schema': 'https://json-schema.org/draft/2020-12/schema',
      description: 'A schema for unit testing',
      type: 'object',
      properties: [Object],
      required: [Array]
    },
    schemaId: '$id',
    root: [Circular *1],
    baseId: 'https://www.example.com/schemas/test',
    schemaPath: undefined,
    localRefs: {},
    meta: undefined,
    '$async': undefined,
    validateName: ValueScopeName {
      str: 'validate20',
      prefix: 'validate',
      value: [Object],
      scopePath: [_Code]
    },
    validate: [Circular *2]
  },
  evaluated: {
    props: { foo: true, bar: true, baz: true },
    items: undefined,
    dynamicProps: false,
    dynamicItems: false
  }
}

What results did you expect? No warning. The spec has specifically changed the way to declare tuples and arrays to avoid this sort of confusion and I'm not sure the warning is still needed

Are you going to resolve the issue? You mean through an PR? I can certainly do that if that's wanted

KuSh avatar Mar 15 '23 10:03 KuSh

it's a possible enhancement to make strictTuples behave differently in draft2020-12. You still can define open tuples in 2020-12, and the idea of this option is to prevent you from using open tuples as they are better avoided in JSON. A stronger opinion that JTD enforces is that any tuples are better avoided in JSON as there is no cross-platform support for them, but it's another story.

epoberezkin avatar Apr 21 '23 08:04 epoberezkin

I can't figure out an incantation for draft 2020-12 for a 4x4 matrix which doesn't throw an error in strict mode. Thrown error is below, with ajv 8.12.0. Suggestions are welcome.

        "@matrix": {
          "$comment": "SFMatrix4f inputOutput",
          "type": "array",
          "prefixItems": [
            {
              "default": 1,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 1,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 1,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 0,
              "type": "number"
            },
            {
              "default": 1,
              "type": "number"
            }
          ],
      "items": { "type": "number" },
          "minItems": 16,
          "maxItems": 16
        },

Error thrown is:

Error: strict mode: "prefixItems" is 16-tuple, but minItems or maxItems/items are not specified or different at path "#/oneOf/1/properties/%40matrix" at checkStrictMode (C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\util.js:174:15) at checkStrictTuple (C:\Users\john\x3dvalidate\node_modules\ajv\dist\vocabularies\applicator\items.js:46:40) at validateTuple (C:\Users\john\x3dvalidate\node_modules\ajv\dist\vocabularies\applicator\items.js:24:5) at Object.code (C:\Users\john\x3dvalidate\node_modules\ajv\dist\vocabularies\applicator\prefixItems.js:9:46) at keywordCode (C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\validate\index.js:464:13) at C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\validate\index.js:222:17 at CodeGen.code (C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\codegen\index.js:439:13) at CodeGen.block (C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\codegen\index.js:568:18) at iterateKeywords (C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\validate\index.js:219:9) at groupKeywords (C:\Users\john\x3dvalidate\node_modules\ajv\dist\compile\validate\index.js:200:13)

The JSON being evaluated doesn't even have @matrix property.

I would love to use strict mode, but it's fouling up my user's logs with nonsense. I am getting older, and my vision may be failing!

Thanks!

coderextreme avatar Aug 25 '23 12:08 coderextreme