dianping/cat · error · SyntaxError
Expected {name} at line {line}, col {col}.
Error message
Expected {name} at line {line}, col {col}. What it means
Thrown by the CSS worker's `TokenStream.mustMatch(tokenTypes)` when the next token(s) do not match a token type the grammar requires (selector colon, semicolon, closing brace, etc.). `mustMatch` is the parser's assertion operator: after the failed match it reads the actual lookahead token (`LT(1)`) and throws a `SyntaxError` naming the expected token type and the actual token's position. It means the statement was structurally incomplete or malformed at that point.
Source
Thrown at cat-home/src/main/webapp/assets/js/editor/worker-css.js:1591
while(i < len){
if (tt == tokenTypes[i++]){
return true;
}
}
this.unget();
return false;
},
mustMatch: function(tokenTypes, channel){
var token;
if (!(tokenTypes instanceof Array)){
tokenTypes = [tokenTypes];
}
if (!this.match.apply(this, arguments)){
token = this.LT(1);
throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
" at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
}
},
advance: function(tokenTypes, channel){
while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){
this.get();
}
return this.LA(0);
},
get: function(channel){
var tokenInfo = this._tokenData,
reader = this._reader,
value,
i =0,
len = tokenInfo.length,View on GitHub (pinned to e815e74d4c)
Solutions
- Go to the line/col in the message and add the token named as 'Expected {name}' (e.g. insert the missing `;`, `:`, `{`, `}` or `)`).
- Look backwards from the reported position — the real mistake is usually an unterminated earlier rule (missing `}` or `;`) that shifted the parser onto the wrong token.
- Run the stylesheet through CSSLint/stylelint to get all mustMatch failures at once instead of fixing one per parse.
- If the CSS is machine-generated, fix the generator rather than patching output.
Example fix
/* before */
.menu { color: red }
.footer { color: blue; } /* mustMatch(RBRACE/SEMICOLON) may fire on malformed earlier rules */
/* after */
.menu { color: red; }
.footer { color: blue; } Defensive patterns
Strategy: try-catch
Validate before calling
function quickSanity(css) {
var depth = 0;
for (var i = 0; i < css.length; i++) {
if (css[i] === '{') depth++;
if (css[i] === '}') depth--;
if (depth < 0) return 'unexpected } at index ' + i;
}
return depth === 0 ? null : 'missing ' + depth + ' closing brace(s)';
} Try / catch
try {
parser.parse(css);
} catch (ex) {
if (ex.line && ex.col) { jumpTo(ex.line, ex.col, ex.message); return; } // SyntaxError carries position
throw ex;
} Prevention
- Brace-balance check before parsing machine-produced CSS.
- Use an editor with live CSS linting so missing tokens surface while typing.
- Fix the FIRST reported error then re-parse — later positions are usually collateral.
- Keep the parser in non-strict mode and render 'error' events inline instead of letting one throw abort everything.
When it happens
Trigger: CSS missing a mandatory token: a declaration without a semicolon before `}` (`a{color:red}`), a media query missing `{`, `@import` without a following string/URL token, a selector missing its block. Any call like `tokenStream.mustMatch(Tokens.SEMICOLON)` / `mustMatch(Tokens.RBRACE)` / `mustMatch(Tokens.COLON)` where the input has something else (or EOF) next.
Common situations: Hand-typing CSS and forgetting `;` or `{}`; minifiers with bugs that drop trailing semicolons inside the wrong block; template literals that interpolate `undefined` leaving a hole where a token was expected; nested preprocessor output with an unclosed block.
Related errors
- Expected "{pattern}" at line {line}, col {col}.
- Unknown @ rule.
- @charset not allowed here.
- @import not allowed here.
- @namespace not allowed here.
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/acb37c70a0bbd3a1.
Report an issue: GitHub.