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

  1. Move all `@import` statements to the top of the stylesheet, immediately after `@charset` and before the first rule.
  2. Better: replace runtime `@import` with build-time inlining (postcss-import, sass `@use`, bundler CSS pipeline) so ordering constraints vanish.
  3. If imports must cascade late, give them higher specificity (`#id`, layered selectors) instead of a later position.
  4. 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

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


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