{"record":{"id":"eb33fce6c884821e","repo":"amruthpillai/reactive-resume","slug":"invalid-name-expression","errorCode":null,"errorMessage":"Invalid :${name} expression.","messagePattern":"Invalid :(.+?) expression\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/resume/src/stylesheet/selector.ts","lineNumber":168,"sourceCode":"\t}\n\n\tconst expression = nth[0].nth;\n\tlet a = 0;\n\tlet b = 0;\n\tif (expression.type === \"Identifier\") {\n\t\tconst keyword = astName(expression).toLowerCase();\n\t\tif (keyword === \"odd\") {\n\t\t\ta = 2;\n\t\t\tb = 1;\n\t\t} else if (keyword === \"even\") {\n\t\t\ta = 2;\n\t\t} else {\n\t\t\tthrow new Error(`Unsupported :${name} expression.`);\n\t\t}\n\t} else if (expression.type === \"AnPlusB\") {\n\t\ta = expression.a === null || expression.a === undefined ? 0 : Number(expression.a);\n\t\tb = expression.b === null || expression.b === undefined ? 0 : Number(expression.b);\n\t\tif (!Number.isInteger(a) || !Number.isInteger(b)) throw new Error(`Invalid :${name} expression.`);\n\t} else {\n\t\tthrow new Error(`Unsupported :${name} expression.`);\n\t}\n\n\tif (name === \"nth-of-type\" && nth[0].selector) throw new Error(\":nth-of-type does not accept an of selector.\");\n\tconst of = nth[0].selector ? compileSelectorList(nth[0].selector, { depth: context.depth + 1 }) : undefined;\n\treturn { type: \"pseudo\", name, a, b, ...(of ? { of } : {}) };\n}\n\nfunction compileSimple(node: SelectorAst, context: CompileContext): CompiledSimpleSelector | null {\n\tswitch (node.type) {\n\t\tcase \"TypeSelector\": {\n\t\t\tconst name = astName(node);\n\t\t\tif (name === \"*\") return { type: \"universal\" };\n\t\t\tif (!knownKinds.has(name)) throw new Error(`Unknown semantic element ${name}.`);\n\t\t\treturn { type: \"type\", name: name as SemanticNode[\"kind\"] };\n\t\t}\n\t\tcase \"IdSelector\":","sourceCodeStart":150,"sourceCodeEnd":186,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/resume/src/stylesheet/selector.ts#L150-L186","documentation":"Thrown by compileNth when an AnPlusB expression has an a or b component that Number() cannot coerce to an integer (Number.isInteger is false). Non-integer or non-numeric steps are rejected so the matcher stays deterministic.","triggerScenarios":"Writing :nth-child(1.5n), :nth-child(n.5), or any An+B whose coefficients parse to a non-integer like NaN.","commonSituations":"Typing a decimal step; css-tree accepting a syntactically valid but semantically non-integer coefficient.","solutions":["Use integer coefficients only: :nth-child(2n+1), :nth-child(3n).","Drop the fractional part: 1.5n becomes 1n or 2n depending on intent.","Validate the coefficient before interpolating it into a generated selector."],"exampleFix":"// before\nitem:nth-child(1.5n+1)\n// after\nitem:nth-child(2n+1)","handlingStrategy":"validation","validationCode":"const integerCoefficients = (a, b) =>\n  (a === '' || a == null || Number.isInteger(Number(a))) &&\n  (b === '' || b == null || Number.isInteger(Number(b)));\n// verify before interpolating into :nth-child(<a>n+<b>)","typeGuard":"const isRejected = (r) => r.selector === null && typeof r.error === 'string';","tryCatchPattern":"const result = compileSelector(selector);\nif (result.selector === null && result.error.startsWith('Invalid :')) {\n  roundCoefficientToInt(selector);\n}","preventionTips":["Use integer-only coefficients in An+B expressions.","Round or reject fractional steps before generating selectors.","Validate generated nth strings with compileSelector before persisting."],"tags":["semantic-css","selector","nth","pseudo-class"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}