Large Definitions cause RangeError: Maximum call stack size exceeded

Hi, i’m using custom renderers (Jsonforms/core & React v.3.2.1) to render my form with ValidateAndHide. I track a touched-state to prevent the initial errors being shown that occur once a user enters data into the form. I also utilize the middleware’s UPDATE_ERRORS & UPDATE_DATA to conditionally show and hide errors depending on the touched-state of every Control and pass them to additionalErrors.
(I’m also getting this error without using my middleware)

Once I started adding production data to my definitions, which added a lot more answers, I consistently started getting:

With custom middleware:

Error caught in boundary RangeError: Maximum call stack size exceeded
    at validate (chunk-FBNQYE4V.js?v=c243922c:11559:17)
    at coreReducer (chunk-FBNQYE4V.js?v=c243922c:11623:17)
    at Object.current (useJsonForms.ts:159:22)
    at @jsonforms_react.js?v=c243922c:234:74
    at mountState (chunk-ZW27HLE7.js?v=c243922c:12025:28)
    at Object.useState (chunk-ZW27HLE7.js?v=c243922c:12565:24)
    at useState (chunk-MWE3B2LM.js?v=c243922c:1066:29)
    at JsonFormsStateProvider (@jsonforms_react.js?v=c243922c:234:53)
    at renderWithHooks (chunk-ZW27HLE7.js?v=c243922c:11568:26)
    at mountIndeterminateComponent (chunk-ZW27HLE7.js?v=c243922c:14946:21)

Without specifying middleware:

chunk-FBNQYE4V.js?v=c243922c:11559 Uncaught RangeError: Maximum call stack size exceeded
    at validate (chunk-FBNQYE4V.js?v=c243922c:11559:17)
    at coreReducer (chunk-FBNQYE4V.js?v=c243922c:11623:17)
    at Object.defaultMiddleware [as current] (chunk-FBNQYE4V.js?v=c243922c:12331:60)
    at @jsonforms_react.js?v=c243922c:234:74
    at mountState (chunk-ZW27HLE7.js?v=c243922c:12025:28)
    at Object.useState (chunk-ZW27HLE7.js?v=c243922c:12565:24)
    at useState (chunk-MWE3B2LM.js?v=c243922c:1066:29)
    at JsonFormsStateProvider (@jsonforms_react.js?v=c243922c:234:53)
    at renderWithHooks (chunk-ZW27HLE7.js?v=c243922c:11568:26)
    at mountIndeterminateComponent (chunk-ZW27HLE7.js?v=c243922c:14946:21)

I have two questions as of right now:

  • is it possible to disable validation of definitions in the schema? (then everything seems to work fine (NoValidation))
  • am I using a good structure for declaring these definitions? Or is there a more efficient one you can suggest? We really need a key-value pair option, as we need to pass a key but show a more descriptive answer to the user.
    I haven’t tried this but would you suggest doing something like this for my definitions instead?
{
  type: 'object'
  enum: [{key: 'value1'}, {key1: 'value2'}]
}

Edit: This seems to work fine. It’s no longer crashing, I started checking AJV’s oneOf implemention and it seems like it’s a bunch of recursive if-statements that occur when using it. Although the downside with this enum approach is that it’s not natively supported in the jsonforms editor.

JsonSchema:

{
  type: 'object',
  properties: {
    companyName: {
      type: 'string',
    },
    organizationNumber: {
      type: 'string',
    },
    streetName: {
      type: 'string',
    },
    coAdress: {
      type: 'string',
    },
    zipCode: {
      type: 'string',
    },
    city: {
      type: 'string',
    },
    country: {
      type: 'string',
      $ref: '#/definitions/countries',
    },
    lei: {
      type: 'string',
      $ref: '#/definitions/yesNo',
    },
    sni: {
      type: 'string',
      $ref: '#/definitions/sni',
    },
   // there are quite a few more properties
  },
  required: [
   // all my required fields
  ],
  definitions: {
    yesNo: {
      type: 'string',
      oneOf: [
        { const: 'yes', title: 'Ja' },
        { const: 'no', title: 'Nej' },
      ],
    },
    sni: {
      type: 'string',
      oneOf: [
        { const: 'key1', title: 'example1' },
        { const: 'key2', title: 'example2' },
       // ..... and 600 more keys 
      ],
    },
    countries: {
      type: 'string',
      oneOf: [
        { const: 'se', title: 'Sweden' },
        { const: 'dk', title: 'Denmark' },
        { const: 'no', title: 'Norway' },
        { const: 'fi', title: 'Finland' },
        // ..... all countries
      ],
    },
  },
}

Please let me know if there are any more details I can provide.

Thank you, J

Hi @joelm,

As you noticed, the problem comes from the oneOf validation in AJV. Sadly it’s not suitable for very large number of oneOf options and errors out with the “maximum call stack size exceeded” error.

You will need to workaround this limitation.

  • You could switch to enums instead of oneOfs. Then via JSON Forms i18n support you can provide alternative labels for the enum values, or
  • You could remove the oneOf from the validation path. For this you can hand over a different schema for the JSON Forms validation in which all the oneOfs are removed. You will then no longer receive validation errors in case an invalid value is set, however typically this is not possible anyway via the UI.
    • You can do this relatively easily with the middleware: Hand over the simplified schema in the INIT action. Then afterwards replace the simplified schema with the real schema when returning the state. Do the same in the UPDATE_CORE action: Hand over a new simplified schema instance if there are schema changes.
  • Alternatively you could remove the oneOf completely from your schema and inject the options manually into an enum renderer.

Of these options, the second one (i.e. modify the schema used for validation) is the easiest to implement and only has a minor downside. So without further context I would recommend that one.