amark/gun · error · Error

not tag in ${a}

Error message

not tag in ${a}

What it means

In lib/normalize.js (jquery-normalize), addUnstable is a callback passed into the mutation functions (exclude, next, parentOrderWrap) that re-queues a node's wrapper object `a` into the unstable list. Before queueing it asserts that the wrapper has a `tag` property; if `a.tag` is missing/falsy it throws 'not tag in '. Note the arguments to Error() are not interpolated, so the message literally reads 'not tag in ' — the offending object `a` is passed as a second, ignored argument.

Source

Thrown at lib/normalize.js:63

      'em': 'i', 'strong': 'b', 'strike': 's',
    }
    ,attrs: {
      'id':1
      ,'class':1
      ,'style':1
    }
    ,blockTag: function(a){
      return a.opt.tags[a.tag].order < a.opt.tags.a.order;
    }
    ,mutate: [exclude, moveSpaceUp, next, parentOrderWrap]
  }

  var defaultOpt = prepareOptTags($.extend(true, {}, baseOpt));

  var unstableList = [];

  function addUnstable(a) { // NOT ES5
    if(!a.tag) { throw Error("not tag in ", a) }
    if(a.unstable) return;
    unstableList.push(a);
    a.unstable = true;
  }

  function initTag(a) {
    // initial handling (container, convert, attributes):
    a.tag = tag(a.$);
      if(empty(a)) {
      return;
    }
    parseAndRemoveAttrs(a);
    convert(a);
    setAttrs(a);
    a.$[0].a = a; // link from dom element back to a
    // state machine init
    unstableList.push(a);
    a.unstable = true;

View on GitHub (pinned to 552227599d)

Solutions

  1. Ensure every object passed to addUnstable went through initTag so a.tag is set.
  2. Check for empty elements (br, img) in the HTML being normalized — initTag returns early for them; don't re-queue their wrappers from custom mutations.
  3. If you supply custom opt.mutate functions, only call addUnstable on wrappers that already have a tag.
  4. Log the object before throwing (Error arguments beyond the first are ignored) to identify the offending node: temporarily change the throw to include JSON.stringify(a).
  5. Upgrade/patch the library — the message construction is buggy (comma instead of concatenation) which hides which tag caused it.

Example fix

// before\nif(!a.tag) { throw Error("not tag in ", a) }\n// after\nif(!a.tag) { throw Error("not tag in " + JSON.stringify(a && a.$ && a.$[0] && a.$[0].outerHTML)) }
Defensive patterns

Strategy: type-guard

Validate before calling

// Guard wrappers before any custom mutate hook re-queues them\nfunction canEnqueue(a){ return a && typeof a === 'object' && a.$ && a.$[0] && !!a.tag; }\n// only call addUnstable when canEnqueue(a) is true

Type guard

function hasTag(a){ return a != null && typeof a === 'object' && typeof a.tag === 'string' && a.tag.length > 0; }

Try / catch

try {\n  $.normalize(html, opt);\n} catch (e) {\n  if (/^not tag in/.test(e.message)) {\n    console.error('normalize state machine hit a wrapper without a tag — check empty elements or custom mutate hooks');\n  } else { throw e; }\n}

Prevention

When it happens

Trigger: A mutation function (exclude, next, or parentOrderWrap) calls addUnstable with an object `a` that never went through initTag, or whose `tag` was never assigned (initTag sets a.tag = tag(a.$); empty nodes return early before a.tag gets fully set up in the state machine path). Typically caused by custom/misconfigured opt.mutate hooks or DOM structures that bypass initTag.

Common situations: Custom normalize options supplying mutate functions that enqueue their own wrappers without a tag; HTML containing empty elements (empty(a) returns early in initTag, leaving a.tag unset) later manipulated by mutations; bugs after refactoring the internal state machine.

Related errors


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