tailwindlabs/tailwindcss · error · CssSyntaxError
Invalid custom property, expected a value
Error message
Invalid custom property, expected a value
What it means
Thrown by the CSS parser while scanning a custom property (a declaration whose name starts with `--`). After collecting the value up to the terminating `}` or end-of-input, it calls `parseDeclaration(buffer, colonIdx)`; if that returns null the declaration is unparseable (typically because the value is empty or malformed) and the parser raises a `CssSyntaxError` with source-location metadata. The message specifically flags custom properties because they have relaxed value rules — failing to parse one usually means the value is missing entirely.
Source
Thrown at packages/tailwindcss/src/css-parser.ts:298
// End of a block.
else if (
peekChar === CLOSE_PAREN ||
peekChar === CLOSE_BRACKET ||
peekChar === CLOSE_CURLY
) {
if (
closingBracketStack.length > 0 &&
input[j] === closingBracketStack[closingBracketStack.length - 1]
) {
closingBracketStack = closingBracketStack.slice(0, -1)
}
}
}
let declaration = parseDeclaration(buffer, colonIdx)
if (!declaration) {
throw new CssSyntaxError(
`Invalid custom property, expected a value`,
source ? [source, start, i] : null,
)
}
if (source) {
declaration.src = [source, start, i]
declaration.dst = [source, start, i]
}
if (parent) {
parent.nodes.push(declaration)
} else {
ast.push(declaration)
}
buffer = ''
}View on GitHub (pinned to 16e94cbf7f)
Solutions
- Give the custom property a concrete value, e.g. `--my-var: #fff;`.
- If the value is intentionally empty/invalid, use a valid placeholder like `--my-var: initial;`.
- Terminate the declaration with a semicolon and ensure the value is non-empty before the closing brace.
- Check generated/templated CSS to confirm the value slot is populated.
Example fix
/* before */
.x {
--brand-color:
}
/* after */
.x {
--brand-color: #3b82f6;
} Defensive patterns
Strategy: validation
Validate before calling
// Reject empty custom property values before sending CSS to Tailwind
function validateCustomProperties(css: string): string[] {
const errors: string[] = [];
for (const m of css.matchAll(/(--[\w-]+)\s*:\s*(?:;|\}|$)/gm)) {
errors.push(`Empty value for custom property ${m[1]}`);
}
return errors;
} Try / catch
try {
const ast = CSS.parse(input);
} catch (e) {
if (e instanceof CssSyntaxError && e.message.includes('Invalid custom property')) {
// surface the source line, offer a fix
} else throw e;
} Prevention
- Always give custom properties a concrete or `initial` value.
- Run a CSS linter (stylelint) before compiling.
- When templating, ensure value slots are non-empty.
When it happens
Trigger: Writing `--my-var: ;` with an empty value at the end of a block without a semicolon, or `--my-var:` followed immediately by `}`, or a custom property whose value consists only of a malformed token the declaration parser rejects. The branch is reached specifically for `--`-prefixed declarations (custom properties).
Common situations: Author error leaving a custom property value blank; a broken `@property` override; generated CSS that emits `--x:` with no value; minifier or preprocessor stripping a value.
Related errors
- Invalid declaration: `${buffer.trim()}`
- Missing opening {
- Missing opening (
- Missing closing } at ${parent.selector}
- Missing closing } at ${parent.name} ${parent.params}
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/424f74ab511c58ee.
Report an issue: GitHub.