dianping/cat · error · SyntaxError
Unknown @ rule.
Error message
Unknown @ rule.
What it means
Thrown by the CSS worker's stylesheet parser when it encounters an `@` token whose at-keyword is not one of the at-rules it implements (`@media`, `@page`, `@import`, `@charset`, `@namespace`, `@font-face`, `@keyframes`/vendor variants, `@supports`-era rules absent here). After the recognized cases fall through, the else branch throws `SyntaxError('Unknown @ rule.')` anchored at the at-token's position. It is a grammar-coverage failure: the CSS is (or may be) valid, but this parser build does not know the rule.
Source
Thrown at cat-home/src/main/webapp/assets/js/editor/worker-css.js:2049
this.fire({
type: "error",
error: null,
message: "Unknown @ rule: " + tokenStream.LT(0).value + ".",
line: tokenStream.LT(0).startLine,
col: tokenStream.LT(0).startCol
});
count=0;
while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) == Tokens.LBRACE){
count++; //keep track of nesting depth
}
while(count){
tokenStream.advance([Tokens.RBRACE]);
count--;
}
} else {
throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
}
break;
case Tokens.S:
this._readWhitespace();
break;
default:
if(!this._ruleset()){
switch(tt){
case Tokens.CHARSET_SYM:
token = tokenStream.LT(1);
this._charset(false);
throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol);
case Tokens.IMPORT_SYM:
token = tokenStream.LT(1);
this._import(false);
throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol);
case Tokens.NAMESPACE_SYM:
token = tokenStream.LT(1);View on GitHub (pinned to e815e74d4c)
Solutions
- Identify the at-rule at the reported position; if it was a typo (e.g. `@medi`), correct it to a real at-rule.
- If the rule is modern-but-valid (`@supports`, `@layer`, `@container`), move it into a file this parser does not validate, or upgrade/replace worker-css.js with a parser that supports it (postcss, css-tree).
- Strip preprocessor directives (`@mixin`, `@extend`) before handing compiled output to the worker — feed the compiled CSS, not the Sass source.
- Run in non-strict mode and subscribe to the parser's 'error' event so unknown at-rules are reported per-rule instead of aborting the whole parse.
Example fix
/* before */
@supports (display: grid) { .g { display: grid; } } /* parser: Unknown @ rule. */
/* after (option 1: rule this parser knows) */
@media (min-width: 0) { .g { display: block; } }
/* after (option 2): keep @supports and upgrade/swap the CSS parser */ Defensive patterns
Strategy: try-catch
Validate before calling
var KNOWN_AT = /^@(media|page|import|charset|namespace|font-face|(-moz|-o|-webkit|-ms-)?keyframes)\b/;
function preflightAtRules(css) {
var unknown = [];
(css.match(/@[\w-]+/g) || []).forEach(function (r) {
if (!KNOWN_AT.test(r)) unknown.push(r);
});
return unknown; // e.g. ['@supports', '@layer'] -> route around this parser
} Try / catch
try {
parser.parse(css);
} catch (ex) {
if (/Unknown @ rule/.test(ex.message)) { logWarn('skipping modern at-rule at ' + ex.line + ':' + ex.col); return; }
throw ex;
} Prevention
- Scan for at-rules your parser build knows before validating modern CSS.
- Keep worker-css.js updated or move linting to a maintained parser (stylelint/postcss) for modern CSS.
- Feed compiled CSS (never Sass/Less directives) to the plain CSS worker.
- Run non-strict so unknown at-rules become reported events, not fatal throws.
When it happens
Trigger: Stylesheets using at-rules newer or less common than the parser's set: `@supports`, `@document`, `@viewport`, `@counter-style`, `@font-feature-values`, `@layer`, `@container`, `@scope`; or a typo'd at-rule like `@medi (min-width:0)`. Parsing such input through this worker's `parse()`/`_stylesheet()` path.
Common situations: Modern CSS shipped to an older bundled worker-css.js (common in long-lived apps and CMS installs); CSS written for a preprocessor (`@extend`, `@mixin` from Sass) accidentally fed to the plain CSS parser; vendor-specific at-rules the token table lacks.
Related errors
- @charset not allowed here.
- @import not allowed here.
- @namespace not allowed here.
- Expected "{pattern}" at line {line}, col {col}.
- Expected {name} at line {line}, col {col}.
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/c67ffcc746b149fa.
Report an issue: GitHub.