{"record":{"id":"c5e07adff60aa9ff","repo":"amruthpillai/reactive-resume","slug":"selector-is-too-long","errorCode":null,"errorMessage":"Selector is too long.","messagePattern":"Selector is too long\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/resume/src/stylesheet/selector.ts","lineNumber":283,"sourceCode":"\tcompounds.push({ selectors });\n\tconst specificity = SpecificityCalculator.calculateForAST(node).toArray();\n\treturn { compounds, combinators, specificity: [specificity[0], specificity[1], specificity[2]] };\n}\n\nfunction compileSelectorList(node: SelectorAst, context: CompileContext): readonly CompiledComplexSelector[] {\n\tif (node.type !== \"SelectorList\") throw new Error(\"Expected a SelectorList AST.\");\n\tconst selectors = childrenOf(node);\n\tif (selectors.length === 0 || selectors.length > SEMANTIC_CSS_LIMITS_V1.maxSelectorsPerRule) {\n\t\tthrow new Error(\"Selector list has an unsupported number of selectors.\");\n\t}\n\treturn selectors.map((selector) => compileComplex(selector, context));\n}\n\nexport function compileSelector(source: string | CssNode): CompileSelectorResult {\n\ttry {\n\t\tconst text = typeof source === \"string\" ? source : csstree.generate(source);\n\t\tif (Array.from(text).length > SEMANTIC_CSS_LIMITS_V1.maxSelectorCodePoints)\n\t\t\tthrow new Error(\"Selector is too long.\");\n\t\tconst ast = (\n\t\t\ttypeof source === \"string\" ? csstree.parse(source, { context: \"selectorList\", positions: true }) : source\n\t\t) as SelectorAst;\n\t\treturn { selector: { selectors: compileSelectorList(ast, { depth: 0 }) } };\n\t} catch (error) {\n\t\treturn { selector: null, error: error instanceof Error ? error.message : \"Invalid selector.\" };\n\t}\n}\n\nexport function getSpecificity(_source: string): Specificity | null {\n\treturn compileSelector(_source).selector?.selectors[0]?.specificity ?? null;\n}\n\nfunction buildTree(root: SemanticNode): Map<string, TreeNode> {\n\tconst nodes = new Map<string, TreeNode>();\n\tconst rootNode: TreeNode = { node: root, parent: null, children: [] };\n\tconst stack = [{ source: root, target: rootNode }];\n\tnodes.set(root.key, rootNode);","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/resume/src/stylesheet/selector.ts#L265-L301","documentation":"Thrown by compileSelector before parsing, when the selector source text exceeds SEMANTIC_CSS_LIMITS_V1.maxSelectorCodePoints (2048 Unicode code points, measured via Array.from(text).length to count astral-plane characters correctly). This is a length guard to bound parsing and storage cost for the restricted semantic engine. Note this is per-selector-list, not per-rule, and is checked on the string (or css-tree-regenerated text) before csstree.parse runs.","triggerScenarios":"Passing a selector string longer than 2048 code points to compileSelector. Passing a CssNode whose regenerated text (csstree.generate) exceeds 2048 code points. Machine-generated selectors with extremely long attribute value lists or deeply nested :is() content whose textual form balloons past the limit.","commonSituations":"Embedding large data values in attribute selectors (e.g. matching against a long URL or blob). Auto-generated selectors that inline many alternatives. A dynamically assembled selector that accidentally includes a large payload (base64, JSON) as an attribute value.","solutions":["Shorten the selector to <= 2048 code points; move large data out of selector attribute values and into the semantic node attributes themselves where matching is direct.","If a CssNode input is too long when regenerated, refactor the AST to be smaller before passing it in.","Check the length with Array.from(selectorText).length at authoring/generation time and split or simplify before calling compileSelector."],"exampleFix":"// before: attribute value bloats the selector past 2048 code points\nconst source = `item[data-url=\"${veryLongString}\"]`;\nconst { error } = compileSelector(source);\n// error === 'Selector is too long.'\n\n// after: store the value on the node and select by a stable key/role\nconst source = 'item[role=\"link\"]';","handlingStrategy":"validation","validationCode":"const MAX_CP = 2048; // SEMANTIC_CSS_LIMITS_V1.maxSelectorCodePoints\nconst codePoints = Array.from(source).length;\nif (codePoints > MAX_CP) {\n  // shorten or reject before compileSelector\n}","typeGuard":"function selectorLengthOk(source: string): boolean {\n  return Array.from(source).length <= 2048;\n}","tryCatchPattern":"const { selector, error } = compileSelector(source);\nif (!selector && error === 'Selector is too long.') {\n  // truncate/simplify and retry\n}","preventionTips":["Never embed large data (URLs, blobs) in selector attribute values.","Measure with Array.from(str).length to correctly count astral code points.","Validate length before persisting a generated selector."],"tags":["css","semantic-stylesheet","selector","limit","unicode"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}