jsonschema2md icon indicating copy to clipboard operation
jsonschema2md copied to clipboard

Maximum call stack size exceeded

Open Finkman opened this issue 5 years ago • 11 comments

What did you do

  • Update jsonschema2md to v4.1.1
  • ran conversion for single schema file

What did you expect to happen

Conversion to mark down without errors

What happened

Since v4.0.4 it fails with an exception:

(Figured out, that it is not guaranteed to fail, sometimes it just works; I know, those are the worst bugs ever)

converter failed with exception
[build] (node:19698) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
[build]     at Array.join (native)
[build]     at keyword (/usr/lib/node_modules/@adobe/jsonschema2md/lib/keywords.js:16:14)
[build]     at Object.meta.(anonymous function) (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:42:28)
[build]     at Object.get (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:104:26)
[build]     at Object.meta.(anonymous function) (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:46:20)
[build]     at Object.get (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:104:26)
[build]     at Object.meta.(anonymous function) (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:46:20)
[build]     at Object.get (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:104:26)
[build]     at Object.meta.(anonymous function) (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:46:20)
[build]     at Object.get (/usr/lib/node_modules/@adobe/jsonschema2md/lib/schemaProxy.js:104:26)
[build] [100%] Converting json schema files to markdown
[build] loading schemas

What's your environment

  • Operating System: Ubuntu 18.04
  • node.js version: v10.20.1

Do you have example files:

For this schema

{
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "http://tqswip.com/common/controlling/controller",
"title": "Controller Configuration",
"type": "object",
"properties": {
  "ProcessData": {
    "title": "Named data variables used in jobs",
    "type": "array",
    "items": {
      "type": "string"
    }
  },
  "RtpcMapping": {
    "title": "Mapping between ProcessData and Rtpc Parameter",
    "description": "Parameter are requested on Rtpc and will be assigned to the process data as configured.",
    "type": "object",
    "propertyNames": {
      "enum": [
        "Gewicht_Netto",
        "Gewicht_Avr",
        "Volumen"
      ]
    },
    "patternProperties": {
      "": {
        "type": "string"
      }
    }
  },
  "Segments": {
    "title": "Processing Segment Definitions",
    "type": "array",
    "items": {
      "$ref": "#/definitions/segment"
    }
  }
},
"required": [
  "Segments",
  "ProcessData",
  "RtpcMapping"
],
"examples": [
  {
    "ProcessData": [
      "huhu"
    ],
    "RtpcMapping": {
      "Gewicht_Netto": "huhu"
    },
    "Segments": [
      {
        "id": 12,
        "Name": "huhu",
        "Sequence": [
          {
            "Type": "jolo",
            "huu": 12
          },
          {
            "Type": "jolo",
            "Inputs": {
              "Grading": "huhu"
            }
          },
          {
            "Sequence": [
              {
                "Type": "123",
                "maxV": 23
              }
            ]
          }
        ]
      }
    ]
  }
],
"definitions": {
  "segmentSchema": {
    "type": "object",
    "properties": {
      "id": {
        "type": "number"
      },
      "Name": {
        "type": "string"
      }
    },
    "required": [
      "id"
    ]
  },
  "segmentNames": {
    "enum": [
      "id",
      "Name"
    ]
  },
  "jobSchema": {
    "type": "object",
    "properties": {
      "Type": {
        "type": "string"
      },
      "Inputs": {
        "type": "object",
        "patternProperties": {
          "": {
            "type": "string"
          }
        }
      },
      "Outputs": {
        "type": "object",
        "patternProperties": {
          "": {
            "type": "string"
          }
        }
      }
    },
    "required": [
      "Type"
    ],
    "not": {
      "anyOf": [
        {
          "required": [
            "Sequence"
          ]
        },
        {
          "required": [
            "Parallel"
          ]
        }
      ]
    }
  },
  "jobNames": true,
  "combinedJobSchema": {
    "type": "object",
    "oneOf": [
      {
        "properties": {
          "Sequence": {
            "type": "array",
            "items": {
              "type": "object",
              "allOf": [
                {
                  "$ref": "#/definitions/anyJobSchema"
                },
                {
                  "if": {
                    "required": [
                      "Type"
                    ]
                  },
                  "then": {
                    "propertyNames": {
                      "$ref": "#/definitions/jobNames"
                    }
                  },
                  "else": {
                    "propertyNames": {
                      "$ref": "#/definitions/combinedJobNames"
                    }
                  }
                }
              ]
            }
          }
        },
        "anyOf": [
          {
            "required": [
              "Sequence"
            ]
          },
          {
            "required": [
              "Parallel"
            ]
          }
        ]
      }
    ],
    "not": {
      "required": [
        "Type"
      ]
    }
  },
  "combinedJobNames": {
    "enum": [
      "Sequence",
      "Parallel"
    ]
  },
  "anyJobSchema": {
    "if": {
      "required": [
        "Type"
      ]
    },
    "then": {
      "$ref": "#/definitions/jobSchema"
    },
    "else": {
      "$ref": "#/definitions/combinedJobSchema"
    }
  },
  "segment": {
    "type": "object",
    "allOf": [
      {
        "$ref": "#/definitions/segmentSchema"
      },
      {
        "$ref": "#/definitions/anyJobSchema"
      },
      {
        "if": {
          "required": [
            "Type"
          ]
        },
        "then": {
          "propertyNames": {
            "anyOf": [
              {
                "$ref": "#/definitions/segmentNames"
              },
              {
                "$ref": "#/definitions/jobNames"
              }
            ]
          }
        },
        "else": {
          "propertyNames": {
            "anyOf": [
              {
                "$ref": "#/definitions/segmentNames"
              },
              {
                "$ref": "#/definitions/combinedJobNames"
              }
            ]
          }
        }
      }
    ]
  }
}
}

Finkman avatar Apr 16 '20 11:04 Finkman

Do you have the issue on other node versions? The code that is failing looks like this:

function keyword(str) {
  used.add(str[0]);
  return str.join('');
}

and I'm having a very hard time visualizing what might cause the issue.

trieloff avatar Apr 17 '20 10:04 trieloff

I've added a speculative fix in the max-call-stack branch. Can you try this and report back?

trieloff avatar Apr 17 '20 10:04 trieloff

Same, but looks like different location throwing:

loading 1 schemas
(node:8415) UnhandledPromiseRejectionWarning: RangeError: Maximum call stack size exceeded
    at Set.add (<anonymous>)
    at keyword (/home/fins/Development/jsonschema2md/lib/keywords.js:15:8)
    at Object.meta.(anonymous function) (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:41:23)
    at Object.get (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:104:26)
    at Object.meta.(anonymous function) (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:46:20)
    at Object.get (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:104:26)
    at Object.meta.(anonymous function) (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:46:20)
    at Object.get (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:104:26)
    at Object.meta.(anonymous function) (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:46:20)
    at Object.get (/home/fins/Development/jsonschema2md/lib/schemaProxy.js:104:26)
(node:8415) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:8415) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Finkman avatar Apr 20 '20 06:04 Finkman

Can you reproduce the error?

Finkman avatar Apr 29 '20 06:04 Finkman

I haven't been able to look into this in depth, sorry.

trieloff avatar Apr 29 '20 08:04 trieloff

Same issue with schemas including multiple objects in "definitions". With those files I have found a workaround by removing the "$id" keyword. Any hint?

eriesgo avatar May 12 '20 17:05 eriesgo

@trieloff I have discovered that removing the recursive references in my code fixed the stack overflow.

eriesgo avatar May 15 '20 16:05 eriesgo

This issue may be related to another issue #234

Windol avatar Jun 25 '20 14:06 Windol

I've had this bug, too, and I think it's because I have an object type that may contain itself. Recursion bad. Deleting the recursive property made it run fine. Probably need to handle recursive references.

miscounting avatar Jun 30 '20 21:06 miscounting

Recursion references are perfectly legit in JSON Schema. jsonschema2md should be smart enough to handle this

sjovanovic avatar Jul 20 '20 16:07 sjovanovic

Also just encountered this issue with recursion. Don't really want to change my schema because of this :/

Aulig avatar Apr 23 '21 18:04 Aulig