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

  1. Keep the string on one line, or escape the line break with `\A` (for content) / a backslash-newline continuation.
  2. Close the quote before the line break and reopen it on the next line if concatenation is intended.
  3. 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

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


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