"function nested too deeply" error when enum has many options

Hello! We have an enum with 266 options.

WIth the upgrade to JSONForm 3 from 2.5, we’re seeing the following stack trace:

    Uncaught InternalError: function nested too deeply
    validate core.ts:55
    coreReducer core.ts:167
    <anonymous> JsonFormsContext.tsx:126
    JsonFormsStateProvider JsonFormsContext.tsx:123
    unstable_runWithPriority scheduler.development.js:468

I was able to reproduce in the material renderers example set with 300 options, using the following schemas (I removed the options for length!):

const schema = {
  "properties": {
    "too_many_options": {
      "oneOf": [
{const: "test1", title: "test1"},
{const: "test2", title: "test2"},
...
{const: "test296", title: "test296"},
{const: "test297", title: "test297"},
{const: "test298", title: "test298"},
{const: "test299", title: "test299"},
{const: "test300", title: "test300"},
      ]
    }
  }
};

const uischema = {
  "type": "VerticalLayout",
  "elements": [
    {
      "type": "Control",
      "label": "More options than any sane person could want",
      "scope": "#/properties/too_many_options"
    }
  ]
};

This is a pretty simple set of schemas but please let me know if there’s something I can change to make this work!

2 Likes

So one way to get rid of this error is to set validationMode='NoValidation'. But we do need validation for fields other than this very large drop-down.

I’m reading up on ajv now trying to see if there’s something I can tweak in that configuration.

Hi @sarahtrefethen,

This is interesting, so it seems like this an AJV issue? Can you reproduce the problem simply by using AJV? You can create an AJV instance as used within JSON Forms by calling createAjv() which we offer in @jsonforms/core.

Hi Stefan!

We are already using a custom AJV instance, and I would love to find a setting that would address this. AJV does offer an option to change validation of enums to a loop (Ajv options | Ajv JSON schema validator) but this is a oneOf.

It’s worth noting that this problem happens with the examples in the JSONforms repository at the 300 option mark in Firefox and Chromium. It needs to go up much higher in Chrome (I now have an example with 1000 options, which breaks.) Our app crashes much earlier in chrome, I imagine because of other processes using up resources.

Hi @sarahtrefethen,

If you use the oneOf of title,const pairs simply to have proper labels for enums in the UI then you have an alternative approach available: Use regular enums (which allows you to use the AJV loop option) and then deliver proper labels for the enums via our i18n support.

Note that his requires the i18n function to be very performant as we currently call it on every data change. If not then I would recommend to memoize its internal lookups for your form instance.

Another alternative is to just use a custom renderer and model the enums outside of JSON Schema, skipping AJV completely. This is usually the approach for large enums which are often not even known beforehand and are just fetched dynamically from an API.

1 Like

Hi @sdirix!

Thank you so much for your response. I think you’ve given me the answer but I could use a little more guidance on implementing it.

We are, in fact, populating these dropdown from an API call, so I would like to make a custom renderer. Is there any way to do this without changing the format of our schemas? I tried replacing the OneOf control, but the values I’m passing into the component from outside the schema are failing validation against the placeholder values we have in our schema.

I can see how I could do a custom tester with a key word in the scope, but modifying the schemas we have in use is going to be difficult.

Thank you so much for your help!

Hi @sarahtrefethen,

The schema needs to fit to the data as otherwise you will have validation errors. If you’re unable to adapt the schemas on the backend (or wherever they are coming from) you could still preprocess them before handing them over to JSON Forms and replace the oneOf with a simple string property.

1 Like