dianping/cat · error · SyntaxError

Unexpected token '{value}' at line {line}, col {col}.

Error message

Unexpected token '{value}' at line {line}, col {col}.

What it means

Thrown by the parser's `_unexpectedToken(token)` helper — its generic 'this token cannot appear here' signal. Its main caller is `_verifyEnd()`, which asserts that after a top-level construct is parsed only EOF remains; any trailing token (e.g. a stray `}` or `;` after the stylesheet's rules, or leftovers after skipping an unknown construct) triggers the throw with the offending token's value and position.

Source

Thrown at cat-home/src/main/webapp/assets/js/editor/worker-css.js:3462

                    } else {
                        throw ex;
                    }
                }

            },
            _readWhitespace: function(){

                var tokenStream = this._tokenStream,
                    ws = "";

                while(tokenStream.match(Tokens.S)){
                    ws += tokenStream.token().value;
                }

                return ws;
            },
            _unexpectedToken: function(token){
                throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
            },
            _verifyEnd: function(){
                if (this._tokenStream.LA(1) != Tokens.EOF){
                    this._unexpectedToken(this._tokenStream.LT(1));
                }
            },
            _validateProperty: function(property, value){
                Validation.validate(property, value);
            },

            parse: function(input){
                this._tokenStream = new TokenStream(input, Tokens);
                this._stylesheet();
            },

            parseStyleSheet: function(input){
                return this.parse(input);
            },

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Go to the reported line/col — the token printed in the message is the exact character that shouldn't be there; delete it (usually a surplus `}` or `;`).
  2. Run an brace/paren balance check over the file; an unmatched `{` earlier shifts everything and produces this error far from the cause.
  3. Auto-format (Prettier/stylelint --fix) the file — formatters surface unbalanced blocks immediately.
  4. In non-strict mode, read the fired 'error' events sequentially: the first one usually marks the true imbalance point.

Example fix

/* before */
.a { color: red; }
}              /* Unexpected token '}' — surplus brace */

/* after */
.a { color: red; }
Defensive patterns

Strategy: try-catch

Validate before calling

function balanced(css) {
  var d = 0;
  for (var i = 0; i < css.length; i++) {
    if (css[i] === '{') d++;
    else if (css[i] === '}') { if (--d < 0) return 'extra } at ' + i; }
  }
  return d ? 'missing } x' + d : null;
}

Try / catch

try {
  parser.parse(css);
} catch (ex) {
  if (/Unexpected token/.test(ex.message) && ex.line) { jumpTo(ex.line, ex.col); return; }
  throw ex;
}

Prevention

When it happens

Trigger: Extra closing `}` at end of file so a rule's parse ends early and garbage remains; stray `;` or junk tokens after a completed rule that `_verifyEnd()` then sees; skipping an unknown @-rule leaves tokens the walker didn't consume; mismatched braces anywhere that make nesting bookkeeping end mid-file.

Common situations: Deleting a rule and leaving its closing brace; merge conflicts producing doubled `}}`; minified CSS with an off-by-one brace; hand-rolled CSS concatenation joining fragments without balancing braces.

Understand the failure class

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/1688d29c9a499b83. Report an issue: GitHub.