dianping/cat · error · Error
attribute equal must after attrName
Error message
attribute equal must after attrName
What it means
Error from the hand-rolled SAX attribute state machine in the ACE XML worker (worker-xml.js:~1517). The tokenizer walks a start tag character by character with states S_TAG/S_ATTR/S_EQ/S_V/S_E/S_C; an '=' is legal only in S_ATTR (right after an attribute name) or S_ATTR_S. In any other state the '=' is meaningless, so the parser throws to abort the tag scan.
Source
Thrown at cat-home/src/main/webapp/assets/js/editor/worker-xml.js:1517
return t;
}
function parseElementStartPart(source,start,el,entityReplacer,errorHandler){
var attrName;
var value;
var p = ++start;
var s = S_TAG;//status
while(true){
var c = source.charAt(p);
switch(c){
case '=':
if(s === S_ATTR){//attrName
attrName = source.slice(start,p);
s = S_EQ;
}else if(s === S_ATTR_S){
s = S_EQ;
}else{
throw new Error('attribute equal must after attrName');
}
break;
case '\'':
case '"':
if(s === S_EQ){//equal
start = p+1;
p = source.indexOf(c,start)
if(p>0){
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
el.add(attrName,value,start-1);
s = S_E;
}else{
throw new Error('attribute value no end \''+c+'\' match');
}
}else if(s == S_V){
value = source.slice(start,p).replace(/&#?\w+;/g,entityReplacer);
el.add(attrName,value,start);
errorHandler.warning('attribute "'+attrName+'" missed start quot('+c+')!!');View on GitHub (pinned to e815e74d4c)
Solutions
- Fix the tag so every '=' directly follows an attribute name: <tag attr="value">.
- Remove stray '=' characters or duplicated equals inside the flagged start tag.
- If template syntax (e.g. {{...}} or =expr) is intentional, route the buffer through a worker/mode that understands that template language instead of the XML worker.
Example fix
<!-- before --> <div =class="box">...</div> <!-- after --> <div class="box">...</div>
Defensive patterns
Strategy: validation
Validate before calling
// Before parsing user XML, reject tags with '=' not preceded by a name:
function attributesWellFormed(tagText) {
return /^<\s*[\w:.-]+(\s+[\w:.-]+\s*=\s*("[^"]*"|'[^']*'|\S+))?\s*\/?>$/.test(tagText.trim());
} Try / catch
try {
parseStartTag(source, start, tagNameReplacer);
} catch (ex) {
if (/attribute/.test(ex.message)) reportXmlError(ex); else throw ex;
} Prevention
- Always write name=value pairs; '=' never stands alone.
- Run xmllint on generated XML in CI.
- Remember the worker re-parses per keystroke — transient tag errors are normal while typing.
When it happens
Trigger: Malformed attribute syntax such as '<tag =foo>' (equals before any name), '<tag a=="1">' (double equals), or '<tag a b="x">=' sequences where the scanner meets '=' after a value or quote state. The switch default at line 1513-1515 throws.
Common situations: Hand-edited or templated XML/JSP/HTML where an attribute placeholder got mangled, templating engines emitting '=expr' bindings into an XML worker, or partial typing in the editor while the worker re-parses on each keystroke.
Related errors
- attribute value must after "="
- attribute value missed!!
- invalid attribute:{qName}
- attribute value no end '{c}' match
- attribute invalid close char('/')
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/2b1b26cce2687721.
Report an issue: GitHub.