tailwindlabs/tailwindcss · error · CssSyntaxError

Invalid declaration: `${buffer.trim()}`

Error message

Invalid declaration: `${buffer.trim()}`

What it means

Thrown by the CSS parser at a top-level semicolon (`;`) when the buffered declaration cannot be parsed by `parseDeclaration(buffer)`. This branch fires for normal (non-custom-property) declarations terminated by `;`. An empty buffer is silently skipped (`buffer.length === 0 continue`), so the error specifically means there is non-empty text that still is not a valid `property: value` pair — e.g. no colon, or a malformed token sequence.

Source

Thrown at packages/tailwindcss/src/css-parser.ts:367

    // End of a declaration.
    //
    // E.g.:
    //
    // ```css
    // .foo {
    //   color: red;
    //             ^
    // }
    // ```
    //
    else if (
      currentChar === SEMICOLON &&
      closingBracketStack[closingBracketStack.length - 1] !== ')'
    ) {
      let declaration = parseDeclaration(buffer)
      if (!declaration) {
        if (buffer.length === 0) continue
        throw new CssSyntaxError(
          `Invalid declaration: \`${buffer.trim()}\``,
          source ? [source, bufferStart, i] : null,
        )
      }

      if (source) {
        declaration.src = [source, bufferStart, i]
        declaration.dst = [source, bufferStart, i]
      }

      if (parent) {
        parent.nodes.push(declaration)
      } else {
        ast.push(declaration)
      }

      buffer = ''
    }

View on GitHub (pinned to 16e94cbf7f)

Solutions

  1. Ensure the line is `property: value;`, e.g. `color: red;`.
  2. Remove stray fragments (lone selectors, bare values) that sit where a declaration is expected.
  3. If the text is meant to be a selector or nested rule, move it out of the declaration position or wrap it properly.
  4. Validate the CSS with a linter before feeding it to Tailwind.

Example fix

/* before */
.x {
  color red;
}
/* after */
.x {
  color: red;
}
Defensive patterns

Strategy: validation

Validate before calling

// Naive check: every non-empty declaration before ';' must contain a colon
function findColonlessDeclarations(css: string): string[] {
  const bad: string[] = [];
  for (const line of css.split(';')) {
    const trimmed = line.trim();
    if (trimmed && !trimmed.includes(':') && !trimmed.startsWith('@') && !trimmed.startsWith('{') && !trimmed.startsWith('}')) {
      bad.push(trimmed);
    }
  }
  return bad;
}

Try / catch

try {
  const ast = CSS.parse(input);
} catch (e) {
  if (e instanceof CssSyntaxError && e.message.startsWith('Invalid declaration:')) {
    // report the buffer text from the message
  } else throw e;
}

Prevention

When it happens

Trigger: Writing `color red;` (missing colon), `:root;` (stray selector fragment), `12px;` (bare value with no property), or any non-empty token sequence before a `;` that lacks a `prop: value` shape. The closing-bracket stack must not have `)` on top (so semicolons inside parens are not treated as declaration terminators).

Common situations: Author typo dropping the colon; malformed nested CSS; copy-paste of a selector where a declaration was expected; broken CSS from a template.

Related errors


AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12). Data as JSON: /api/errors/ab11a60ba98d5ba1. Report an issue: GitHub.