jsonld.js icon indicating copy to clipboard operation
jsonld.js copied to clipboard

Frame error : "RangeError Maximum call stack exceeded"

Open tfrancart opened this issue 10 months ago • 2 comments

I ran into this error while framing a large JSON-LD file:

/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:76
api.frame = (state, subjects, frame, parent, property = null) => {
            ^

RangeError: Maximum call stack size exceeded
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:76:13)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)
    at api.frame (/home/runner/work/garance/garance/node_modules/jsonld/lib/frame.js:258:15)

Seems like this is induced by some kind of recursive call in the framing algorithm, line 258 of frame.js: https://github.com/digitalbazaar/jsonld.js/blob/main/lib/frame.js#L258

I am reading here that using a "setTimeout" every e.g. 1000 recursive calls may provide the engine the chance to clear the stack: https://stackoverflow.com/a/20999077/189723

tfrancart avatar Mar 05 '25 12:03 tfrancart

I imagine some data patterns might have trouble there. Do you have a short example of the shape of your data and the frame? It's easier to debug these sorts of things with an example to run, and knowing the general shape of the data would help to programatically create a large test case.

davidlehn avatar Mar 06 '25 02:03 davidlehn

Thanks for your answer. I was able to track the problem down. Here is the JSON-LD to be framed, including ~16000 instances of the class rico:Agent on which we apply the framing : garance-for-agents.zip

Here is the frame that gives the error, on the owl:sameAs property at the bottom:

{
  "@context": {
    "id": "@id",
    "type": "@type",
    "graph": "@graph",
    "included": "@included",

    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "owl": "http://www.w3.org/2002/07/owl#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "rico": "https://www.ica.org/standards/RiC/ontology#",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "foaf": "http://xmlns.com/foaf/0.1/",
    "dc": "http://purl.org/dc/elements/1.1/",
    "dcterms": "http://purl.org/dc/terms/",
    "html": "http://www.w3.org/1999/xhtml",
    "an": "http://data.archives-nationales.culture.gouv.fr/",
    "xsd": "http://www.w3.org/2001/XMLSchema#",


    "owl:sameAs": {
      "@id": "owl:sameAs",
      "@container": "@set",
      "@type": "@id"
    },
    "rdfs:label": {
      "@id": "rdfs:label",
      "@container": "@set"
    },
    "rico:isOrWasDescribedBy": {
      "@id": "rico:isOrWasDescribedBy",
      "@container": "@set"
    },
    "rico:isOrWasRegulatedBy": {
      "@id": "rico:isOrWasRegulatedBy",
      "@container": "@set",
      "@type": "@id"
    },
    "rico:history": {
      "@id": "rico:history",
      "@container": "@set"
    },
    "rico:hasOrHadAgentName": {
      "@id": "rico:hasOrHadAgentName",
      "@container": "@set"
    },
    "rico:agentIsTargetOfAgentOriginationRelation": {
      "@id": "rico:agentIsTargetOfAgentOriginationRelation",
      "@container": "@set"
    },
    "rico:agentIsTargetOfPerformanceRelation": {
      "@id": "rico:agentIsTargetOfPerformanceRelation",
      "@container": "@set"
    },
    "skos:prefLabel": {
      "@id": "skos:prefLabel",
      "@container": "@set"
    },
    "skos:altLabel": {
      "@id": "skos:altLabel",
      "@container": "@set"
    }
    
  },

  "@explicit": true,
  "type": [
    "rico:Agent"
  ],
  "rdfs:label": { "@omitDefault": true },
  "rico:history": { "@omitDefault": true },
  "rico:beginningDate": { "@omitDefault": true },
  "rico:endDate": { "@omitDefault": true },
  "rico:birthDate": { "@omitDefault": true },
  "rico:deathDate": { "@omitDefault": true },  
  "rico:hasOrHadAgentName": { 
    "@omitDefault": true,
    "@explicit": true,
    "rico:isOrWasRegulatedBy": { "@omitDefault": true },
    "rico:textualValue": { "@omitDefault": true },
    "rico:type": { "@omitDefault": true },
    "rico:usedFromDate": { "@omitDefault": true },
    "rico:usedToDate": { "@omitDefault": true }
  },
  "rico:agentIsTargetOfAgentOriginationRelation": {
    "@omitDefault": true,
    "@explicit": true
  },
  "rico:agentIsTargetOfPerformanceRelation": {
    "@omitDefault": true,
    "@explicit": true,
    "rico:performanceRelationHasSource": {
      "@explicit": true,
      "@omitDefault": true,
      "rico:hasActivityType": {
        "@explicit": true,
        "@omitDefault": true,
        "skos:prefLabel": {}
      }
    }
  },
  "rico:isOrWasMemberOf": {
    "@omitDefault": true,
    "@explicit": true,
    "rdfs:label": { "@omitDefault": true }
  },
  "rico:hasOrHadSubdivision": {
    "@omitDefault": true,
    "@explicit": true,
    "rdfs:label": { "@omitDefault": true }
  },
  "owl:sameAs": { 
    /* THE PROBLEM IS HERE */
    "@omitDefault": true
  }  
}

The point is that owl:sameAs can point either to external resources, or to one of the 16000 agents inside the JSON-LD. And when this is the case, the framing on these entities takes very long and crashes.

If I set @explicit: true in owl:sameAs (which is what I want, I want only URIs here, with labels), then the problem disappears. Here is the frame that does not gives the error (see the modified owl:sameAs at the end):

{
  "@context": {
    "id": "@id",
    "type": "@type",
    "graph": "@graph",
    "included": "@included",

    "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    "owl": "http://www.w3.org/2002/07/owl#",
    "rdfs": "http://www.w3.org/2000/01/rdf-schema#",
    "rico": "https://www.ica.org/standards/RiC/ontology#",
    "skos": "http://www.w3.org/2004/02/skos/core#",
    "foaf": "http://xmlns.com/foaf/0.1/",
    "dc": "http://purl.org/dc/elements/1.1/",
    "dcterms": "http://purl.org/dc/terms/",
    "html": "http://www.w3.org/1999/xhtml",
    "an": "http://data.archives-nationales.culture.gouv.fr/",
    "xsd": "http://www.w3.org/2001/XMLSchema#",


    "owl:sameAs": {
      "@id": "owl:sameAs",
      "@container": "@set",
      "@type": "@id"
    },
    "rdfs:label": {
      "@id": "rdfs:label",
      "@container": "@set"
    },
    "rico:isOrWasDescribedBy": {
      "@id": "rico:isOrWasDescribedBy",
      "@container": "@set"
    },
    "rico:isOrWasRegulatedBy": {
      "@id": "rico:isOrWasRegulatedBy",
      "@container": "@set",
      "@type": "@id"
    },
    "rico:history": {
      "@id": "rico:history",
      "@container": "@set"
    },
    "rico:hasOrHadAgentName": {
      "@id": "rico:hasOrHadAgentName",
      "@container": "@set"
    },
    "rico:agentIsTargetOfAgentOriginationRelation": {
      "@id": "rico:agentIsTargetOfAgentOriginationRelation",
      "@container": "@set"
    },
    "rico:agentIsTargetOfPerformanceRelation": {
      "@id": "rico:agentIsTargetOfPerformanceRelation",
      "@container": "@set"
    },
    "skos:prefLabel": {
      "@id": "skos:prefLabel",
      "@container": "@set"
    },
    "skos:altLabel": {
      "@id": "skos:altLabel",
      "@container": "@set"
    }
    
  },

  "@explicit": true,
  "type": [
    "rico:Agent"
  ],
  "rdfs:label": { "@omitDefault": true },
  "rico:history": { "@omitDefault": true },
  "rico:beginningDate": { "@omitDefault": true },
  "rico:endDate": { "@omitDefault": true },
  "rico:birthDate": { "@omitDefault": true },
  "rico:deathDate": { "@omitDefault": true },  
  "rico:hasOrHadAgentName": { 
    "@omitDefault": true,
    "@explicit": true,
    "rico:isOrWasRegulatedBy": { "@omitDefault": true },
    "rico:textualValue": { "@omitDefault": true },
    "rico:type": { "@omitDefault": true },
    "rico:usedFromDate": { "@omitDefault": true },
    "rico:usedToDate": { "@omitDefault": true }
  },
  "rico:agentIsTargetOfAgentOriginationRelation": {
    "@omitDefault": true,
    "@explicit": true
  },
  "rico:agentIsTargetOfPerformanceRelation": {
    "@omitDefault": true,
    "@explicit": true,
    "rico:performanceRelationHasSource": {
      "@explicit": true,
      "@omitDefault": true,
      "rico:hasActivityType": {
        "@explicit": true,
        "@omitDefault": true,
        "skos:prefLabel": {}
      }
    }
  },
  "rico:isOrWasMemberOf": {
    "@omitDefault": true,
    "@explicit": true,
    "rdfs:label": { "@omitDefault": true }
  },
  "rico:hasOrHadSubdivision": {
    "@omitDefault": true,
    "@explicit": true,
    "rdfs:label": { "@omitDefault": true }
  },
  "owl:sameAs": { 
    "@omitDefault": true,
    "@explicit": true,
    "rdfs:label": { "@omitDefault": true }
  }  
}

Even if I am able to work around the problem, I would be happy to understand the reason for the crash.

tfrancart avatar Mar 06 '25 06:03 tfrancart