amark/gun · error · Error

Order of '${name}' not defined in hierarchy

Error message

Order of '${name}' not defined in hierarchy

What it means

Within prepareOptTags, after building each tag entry, the code assigns tag.order = opt.hierarchy.indexOf(name) and throws if it is -1. Since the forEach iterates hierarchy itself, this is a defensive invariant: it fires when a name in the hierarchy cannot be found in itself, i.e. the hierarchy array contains a falsy/duplicate-corrupted entry or the name resolved via a mutated tags map doesn't match — practically signaling an inconsistent or malformed hierarchy definition.

Source

Thrown at lib/normalize.js:112

    }
  }

  function prepareOptTags(opt) {
    var name, tag, tags = opt.tags;
    for(name in tags) {
      if(opt.hierarchy.indexOf(name)===-1)
        throw Error('tag "'+name+'" is missing hierarchy definition');
    }
    opt.hierarchy.forEach(function(name){
      if(!tags[name]){
        tags[name] = {attrs: opt.attrs};
      }
      (tag=tags[name]).attrs = $.extend(tag.attrs||{}, opt.attrs);
      tag.name = name; // not used, debug help (REMOVE later?)
      // order
      tag.order = opt.hierarchy.indexOf(name)
      if(tag.order === -1) {
      throw Error("Order of '"+name+"' not defined in hierarchy");
    }
    });
    return opt;
  }

  // GENERAL UTILS

  function get(o, args){ // path arguments as separate string parameters
    if(typeof args === 'string')
      return o[args[0]];
    var i = 0, l = args.length, u;
    while((o = o[args[i++]]) != null && i < l){};
    return i < l ? u : o;
  }

  function has(obj,prop){
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }

View on GitHub (pinned to 552227599d)

Solutions

  1. Ensure the hierarchy array contains only valid, non-empty string tag names with no holes.
  2. Build the hierarchy from a fixed literal list rather than dynamic string concatenation that may inject undefined.
  3. Sanitize: filter the hierarchy (opt.hierarchy = opt.hierarchy.filter(Boolean)) and deduplicate before calling $.normalize.
  4. Verify customOpt isn't accidentally mutating the shared baseOpt; construct options from $.extend(true, {}, baseOpt, customOpt).
  5. Cross-check both validations: first fix any 'missing hierarchy definition' errors, then re-test — the two checks share the same opt object.

Example fix

// before\nhierarchy: ['div', null, 'p', undefined, 'a']  // sparse entries\n// after\nhierarchy: ['div', 'pre', 'p', 'a']            // clean, ordered tag list
Defensive patterns

Strategy: validation

Validate before calling

function validateHierarchy(hierarchy){\n  if (!Array.isArray(hierarchy)) throw new Error('hierarchy must be an array');\n  var seen = {};\n  for (var i = 0; i < hierarchy.length; i++) {\n    var n = hierarchy[i];\n    if (typeof n !== 'string' || !n) throw new Error('invalid hierarchy entry at index '+i);\n    if (seen[n]) throw new Error('duplicate hierarchy entry: '+n);\n    seen[n] = true;\n  }\n}\n// call validateHierarchy(customOpt.hierarchy) before $.normalize(html, customOpt);

Type guard

function isCleanHierarchy(h){ return Array.isArray(h) && h.every(function(n){ return typeof n === 'string' && n.length > 0; }) && new Set(h).size === h.length; }

Try / catch

try {\n  $.normalize(html, customOpt);\n} catch (e) {\n  if (/not defined in hierarchy/.test(e.message)) {\n    console.error('Hierarchy corrupted — rebuild opt from baseOpt:', e.message);\n    opt = prepareOptTags($.extend(true, {}, baseOpt, userOpt)); // retry with a clean copy\n  } else { throw e; }\n}

Prevention

When it happens

Trigger: Passing customOpt with a hierarchy array containing null/undefined or non-string entries (indexOf on the string name then mismatches), or an opt object where tags/hierarchy were programmatically corrupted between the tags-loop check and the order assignment; also via defaultOpt if baseOpt were patched inconsistently.

Common situations: Dynamically generated hierarchy arrays where a variable is undefined; hierarchy arrays built with duplicates or holes (sparse arrays); runtime mutation of the shared baseOpt object; framework integration code assembling options from user input.

Related errors


AI-assisted analysis of amark/gun@552227599d (2026-09-02). Data as JSON: /api/errors/b6f8fee0dd327e1d. Report an issue: GitHub.