amark/gun · error · Error
tag "${name}" is missing hierarchy definition
Error message
tag "${name}" is missing hierarchy definition What it means
prepareOptTags validates custom options passed to $.normalize: every key in opt.tags must also appear in opt.hierarchy. The hierarchy array defines the canonical tag ordering/structure; a tag present in the tags map but absent from the hierarchy has no defined place in the normalization model, so the library refuses to proceed with this error.
Source
Thrown at lib/normalize.js:101
}
function stateMachine() {
if(unstableList.length===0)
return;
var a, i = -1;
while (a = unstableList.pop()) { // PERF: running index is probably faster than shift (mutates array)
a.unstable = false;
$(a.opt.mutate).each(function(i,fn){
return fn && fn(a, addUnstable);
});
}
}
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
View on GitHub (pinned to 552227599d)
Solutions
- Add every tag listed in opt.tags to the opt.hierarchy array, in the desired structural order.
- If the tag needs no special config, add it to hierarchy and let prepareOptTags auto-create tags[name] from opt.attrs.
- Fix typos so the tags key exactly matches a hierarchy entry.
- Merge from baseOpt so the default hierarchy (div, pre, ol, ul, li, h1-h6, p, a, b, code, i, span, s, sub, sup, u, br, img) is preserved and extend, not replace, it.
- Validate customOpt before passing: iterate Object.keys(opt.tags) and assert each is in opt.hierarchy.
Example fix
// before\n$.normalize(html, {tags: {section: {attrs:{}}}});\n// after\n$.normalize(html, {hierarchy: ['div','section','p','a','b','i','br','img'], tags: {section: {attrs:{}}}}); Defensive patterns
Strategy: validation
Validate before calling
function validateNormalizeOpt(opt){\n if (!Array.isArray(opt.hierarchy)) throw new Error('opt.hierarchy must be an array');\n Object.keys(opt.tags || {}).forEach(function(name){\n if (opt.hierarchy.indexOf(name) === -1)\n throw new Error('tag "'+name+'" must be added to hierarchy');\n });\n}\n// call validateNormalizeOpt(customOpt) before $.normalize(html, customOpt); Type guard
function optIsConsistent(opt){ return Array.isArray(opt.hierarchy) && !!opt.tags && Object.keys(opt.tags).every(function(n){ return opt.hierarchy.indexOf(n) !== -1; }); } Try / catch
try {\n validateNormalizeOpt(customOpt);\n $.normalize(html, customOpt);\n} catch (e) {\n if (/missing hierarchy definition/.test(e.message)) {\n console.error('Config error: add', e.message.match(/tag "([^"]+)"/)[1], 'to hierarchy');\n } else { throw e; }\n} Prevention
- Whenever you add a tags entry, add the same tag to hierarchy in the same change.
- Extend the base hierarchy rather than replacing it: $.extend(true, {}, baseOpt, customOpt).
- Watch for typos — tags keys must exactly equal hierarchy strings.
- Write a unit test that runs prepareOptTags-equivalent validation on every shipped option preset.
When it happens
Trigger: Calling $.normalize(html, customOpt) where customOpt (deep-merged over baseOpt) adds a tags entry (e.g. tags: {section: {...}}) without adding 'section' to the hierarchy array. Also triggered by typos in a tag name inside tags that don't match any hierarchy entry.
Common situations: Extending the normalizer to support new HTML tags (article, section, figure, custom elements) by only configuring tags; copying a partial customOpt example; deep-extend quirks where $.extend(true, baseOpt, customOpt) merges user tags into the base set while the user's hierarchy list omits base or new tags.
Related errors
AI-assisted analysis of amark/gun@552227599d (2026-09-02).
Data as JSON: /api/errors/b95b862ac9afc770.
Report an issue: GitHub.