tailwindlabs/tailwindcss · error · CssSyntaxError
Unterminated string: ${input.slice(startIdx, i) + String.fro
Error message
Unterminated string: ${input.slice(startIdx, i) + String.fromCharCode(quoteChar)} What it means
Thrown by the string scanner when an unescaped newline (LF, or CR+LF) appears inside a quoted string before the closing quote. CSS does not allow raw line breaks inside quoted strings, so the scanner treats a newline as an unterminated string and reports it. The message reconstructs the partial string up to (but not including) the newline and appends the expected quote character.
Source
Thrown at packages/tailwindcss/src/css-parser.ts:709
source ? [source, startIdx, i + 1] : null,
)
}
// End of the line without ending the string.
//
// E.g.:
//
// ```css
// .foo {
// content: "This is a string with a
// ^ Missing "
// }
// ```
else if (
peekChar === LINE_BREAK ||
(peekChar === CARRIAGE_RETURN && input.charCodeAt(i + 1) === LINE_BREAK)
) {
throw new CssSyntaxError(
`Unterminated string: ${input.slice(startIdx, i) + String.fromCharCode(quoteChar)}`,
source ? [source, startIdx, i + 1] : null,
)
}
}
return startIdx
}
View on GitHub (pinned to 16e94cbf7f)
Solutions
- Keep the string on one line, or escape the line break with `\A` (for content) / a backslash-newline continuation.
- Close the quote before the line break and reopen it on the next line if concatenation is intended.
- For dynamic content use a CSS variable set from JS instead of an inline multi-line string.
Example fix
/* before */
.x { content: "hello
world"; }
/* after */
.x { content: "hello world"; } Defensive patterns
Strategy: validation
Validate before calling
// Detect raw newlines inside quoted strings
function findNewlinesInStrings(css: string): string[] {
const bad: string[] = [];
const re = /(["'])((?:\\.|(?!\1).)*?)(\n)/gs;
let m;
while ((m = re.exec(css))) {
if (!m[2].endsWith('\\')) bad.push(m[0]);
}
return bad;
} Try / catch
try {
const ast = CSS.parse(input);
} catch (e) {
if (e instanceof CssSyntaxError && e.message.startsWith('Unterminated string')) {
// the message pinpoints the line; close the quote
} else throw e;
} Prevention
- Never paste raw multi-line text into a CSS string.
- Escape line breaks with \A for content, or keep strings on one line.
- Lint CSS for newlines inside quotes.
When it happens
Trigger: Writing `.x { content: "hello\nworld" }` with an actual line break in the source (rather than an escaped `\A` or `\n`); a quoted string that wraps in the editor without a backslash continuation.
Common situations: Pressing Enter inside a `content:` string; multi-line font-family names; copy-paste of multi-line text into a CSS string.
Related errors
- Unterminated string: ${input.slice(startIdx, i + 1) + String
- Invalid custom property, expected a value
- Invalid declaration: `${buffer.trim()}`
- Missing opening {
- Missing opening (
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/b8ef7fdd81fdbc9c.
Report an issue: GitHub.