tailwindlabs/tailwindcss · error · CssSyntaxError
Missing opening {
Error message
Missing opening { What it means
Thrown when the parser encounters a closing curly brace `}` but the bracket stack (`closingBracketStack`) is empty — meaning there was no matching `{` opened. The check `closingBracketStack === ''` (empty string) fires before slicing the stack. The error is raised with source position `[source, i, i]` pointing at the offending `}`.
Source
Thrown at packages/tailwindcss/src/css-parser.ts:427
// nested nodes are done.
stack.push(parent)
// Make the current node the new parent, so that nested nodes can be
// attached to it.
parent = node
// Reset the state for the next node.
buffer = ''
node = null
}
// End of a block.
else if (
currentChar === CLOSE_CURLY &&
closingBracketStack[closingBracketStack.length - 1] !== ')'
) {
if (closingBracketStack === '') {
throw new CssSyntaxError('Missing opening {', source ? [source, i, i] : null)
}
closingBracketStack = closingBracketStack.slice(0, -1)
// When we hit a `}` and `buffer` is filled in, then it means that we did
// not complete the previous node yet. This means that we hit a
// declaration without a `;` at the end.
if (buffer.length > 0) {
// This can happen for nested at-rules.
//
// E.g.:
//
// ```css
// @layer foo {
// @tailwind utilities
// ^
// }
// ```View on GitHub (pinned to 16e94cbf7f)
Solutions
- Count `{` and `}` braces in the offending file/region and remove the surplus `}`.
- Use an editor with brace-matching to locate the unbalanced closer.
- Run the CSS through a formatter/prettier to surface the mismatch.
- If the input is generated, fix the template that emits the extra brace.
Example fix
/* before */
.x { color: red; }
}
/* after */
.x { color: red; } Defensive patterns
Strategy: validation
Validate before calling
function bracesBalanced(css: string): boolean {
let depth = 0;
for (const ch of css) {
if (ch === '{') depth++;
else if (ch === '}') depth--;
if (depth < 0) return false;
}
return depth === 0;
}
if (!bracesBalanced(input)) throw new Error('Unbalanced curly braces'); Try / catch
try {
const ast = CSS.parse(input);
} catch (e) {
if (e instanceof CssSyntaxError && e.message === 'Missing opening {') {
// locate the extra } via the source coordinates
} else throw e;
} Prevention
- Use an editor with brace matching.
- Format CSS with prettier/stylelint to surface imbalance.
- For generated CSS, unit-test brace balance.
When it happens
Trigger: An extra `}` in the stylesheet (more closers than openers); a `}` after a declaration that was not inside a rule; malformed nested CSS where a block was double-closed. The branch only triggers when the top of the bracket stack is not `)` (parens are tracked separately).
Common situations: Typing an extra `}`; deleting a selector but leaving its closer; broken generated CSS; copy-paste errors merging blocks.
Related errors
- Invalid custom property, expected a value
- Invalid declaration: `${buffer.trim()}`
- 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/3abe2900df7fd576.
Report an issue: GitHub.