dianping/cat · error · SyntaxError
@import not allowed here.
Error message
@import not allowed here.
What it means
Thrown when `@import` appears after rules that must follow it: per CSS grammar, `@import` may only occur before any style rules (and after `@charset`). The parser's default branch attempts `_ruleset()`; failing that, if the token is `IMPORT_SYM` it consumes the `@import` (to skip past it) and throws `SyntaxError('@import not allowed here.')` anchored at the `@import` token. Non-strict mode converts the throw into an 'error' event and parsing continues.
Source
Thrown at cat-home/src/main/webapp/assets/js/editor/worker-css.js:2065
} 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);
this._namespace(false);
throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol);
default:
tokenStream.get(); //get the last token
this._unexpectedToken(tokenStream.token());
}
}
}
} catch(ex) {
if (ex instanceof SyntaxError && !this.options.strict){
this.fire({
type: "error",
error: ex,
message: ex.message,
line: ex.line,View on GitHub (pinned to e815e74d4c)
Solutions
- Move all `@import` statements to the top of the stylesheet, immediately after `@charset` and before the first rule.
- Better: replace runtime `@import` with build-time inlining (postcss-import, sass `@use`, bundler CSS pipeline) so ordering constraints vanish.
- If imports must cascade late, give them higher specificity (`#id`, layered selectors) instead of a later position.
- Validate concatenated output with a linter that flags misplaced `@import` before shipping.
Example fix
/* before */
body { margin: 0; }
@import url("reset.css"); /* @import not allowed here. */
/* after */
@import url("reset.css");
body { margin: 0; } Defensive patterns
Strategy: validation
Validate before calling
function importsFirst(css) {
var firstRule = css.search(/[^@\s/][^{]*\{/); // first char that starts a real rule
var lateImport = /@import/.test(css.slice(firstRule));
return !lateImport;
} Try / catch
try {
parser.parse(css);
} catch (ex) {
if (/@import not allowed/.test(ex.message)) { hoistImports(css).then(parser.parse.bind(parser)); return; }
throw ex;
} Prevention
- Replace runtime @import with build-time inlining (postcss-import, bundler).
- When imports must come later logically, use specificity/layering, not position.
- In concat builds, reorder imports above all rulesets before emitting.
When it happens
Trigger: `@import url("theme.css");` written after a selector rule, a `@media` block, or another `@import` that follows a ruleset; bundlers that append imported files to the bottom of the output; scaffolded CSS where imports were added below existing styles.
Common situations: Developers adding an import at the bottom 'to override styles'; concatenating third-party CSS above project CSS so imports land mid-file; CMS themes injecting content above user CSS that itself starts with `@import`.
Related errors
- Unknown @ rule.
- @charset 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/56d792d6a2c102db.
Report an issue: GitHub.