{"record":{"id":"3eed6811ea2286a7","repo":"dianping/cat","slug":"charset-not-allowed-here","errorCode":null,"errorMessage":"@charset not allowed here.","messagePattern":"@charset not allowed here\\.","errorType":"exception","errorClass":"SyntaxError","httpStatus":null,"severity":"error","filePath":"cat-home/src/main/webapp/assets/js/editor/worker-css.js","lineNumber":2061,"sourceCode":"                                    while(count){\n                                        tokenStream.advance([Tokens.RBRACE]);\n                                        count--;\n                                    }\n\n                                } else {\n                                    throw new SyntaxError(\"Unknown @ rule.\", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);\n                                }\n                                break;\n                            case Tokens.S:\n                                this._readWhitespace();\n                                break;\n                            default:\n                                if(!this._ruleset()){\n                                    switch(tt){\n                                        case Tokens.CHARSET_SYM:\n                                            token = tokenStream.LT(1);\n                                            this._charset(false);\n                                            throw new SyntaxError(\"@charset not allowed here.\", token.startLine, token.startCol);\n                                        case Tokens.IMPORT_SYM:\n                                            token = tokenStream.LT(1);\n                                            this._import(false);\n                                            throw new SyntaxError(\"@import not allowed here.\", token.startLine, token.startCol);\n                                        case Tokens.NAMESPACE_SYM:\n                                            token = tokenStream.LT(1);\n                                            this._namespace(false);\n                                            throw new SyntaxError(\"@namespace not allowed here.\", token.startLine, token.startCol);\n                                        default:\n                                            tokenStream.get();  //get the last token\n                                            this._unexpectedToken(tokenStream.token());\n                                    }\n\n                                }\n                        }\n                    } catch(ex) {\n                        if (ex instanceof SyntaxError && !this.options.strict){\n                            this.fire({","sourceCodeStart":2043,"sourceCodeEnd":2079,"githubUrl":"https://github.com/dianping/cat/blob/e815e74d4c2dd74edac831241f1253fcc7d25381/cat-home/src/main/webapp/assets/js/editor/worker-css.js#L2043-L2079","documentation":"Thrown when `@charset` appears at a position in the stylesheet where it is illegal — it must be the very first statement (only `@charset` may precede it, nothing else). The parser's default branch first tries `_ruleset()`; if that fails and the token is `CHARSET_SYM`, it consumes the rule (so parsing can continue) and then throws `SyntaxError('@charset not allowed here.')` at the `@charset` token's position. In non-strict mode this is caught and fired as an 'error' event instead of aborting.","triggerScenarios":"`@charset \"utf-8\";` placed after any rule, selector block, `@import`, comment-with-rules, or anywhere other than byte-position 0 of the stylesheet; concatenating files where a later fragment contains its own `@charset`; feeding the parser a stylesheet fragment that retains an inner `@charset`.","commonSituations":"Build tools concatenating many CSS files without stripping their individual `@charset` lines; `@import` inlining that leaves the imported file's `@charset` mid-stream; developers pasting a boilerplate header below existing rules.","solutions":["Move the single `@charset \"utf-8\";` to the absolute top of the file, before any rules, comments with rules, or `@import`.","If you concatenate or inline CSS, strip all `@charset` statements except (optionally) one at the head of the output.","Serve the stylesheet as UTF-8 with the right HTTP `Content-Type`/BOM and delete `@charset` entirely — it is rarely needed.","Keep the parser in non-strict mode and surface the fired error event so users see the position instead of a thrown crash."],"exampleFix":"/* before */\n:root { --x: 1; }\n@charset \"utf-8\";   /* @charset not allowed here. */\n\n/* after */\n@charset \"utf-8\";\n:root { --x: 1; }","handlingStrategy":"validation","validationCode":"function charsetOk(css) {\n  var first = css.replace(/^(\\s|\\/\\*[\\s\\S]*?\\*\\/\\s*)*/, '');\n  var count = (css.match(/@charset\\b/g) || []).length;\n  return count === 0 || (count === 1 && /^@charset/.test(first));\n}","typeGuard":null,"tryCatchPattern":"try {\n  parser.parse(css);\n} catch (ex) {\n  if (/@charset not allowed/.test(ex.message)) { css = css.replace(/@charset[^;]+;?\\s*/g, ''); parser.parse(css); return; }\n  throw ex;\n}","preventionTips":["Put @charset at byte 0 or drop it and rely on HTTP charset headers.","Strip @charset from all concatenated fragments in build tooling.","Lint at-rule ordering (@charset → @import → @namespace → rules) in CI."],"tags":["css","parser","at-rule","charset","syntax-error"],"backgroundTag":null,"analyzedSha":"e815e74d4c2dd74edac831241f1253fcc7d25381","analyzedAt":"2026-08-14T14:22:34.512Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}