Skip to content

Invalid code point error on Windows when file path contains backslash + hex UUID #19910

@binoy154

Description

@binoy154

Description

On Windows, Tailwind CSS v4 crashes with Invalid code point when the project path contains a backslash followed by characters that form a valid hex sequence (e.g. a UUID). This affects all v4 versions tested (4.0.17 through 4.2.2).

Error

Invalid code point 11076095
  Plugin: @tailwindcss/vite:generate:serve
  File: E:/projects/BISLiveDeployer/client/src/index.css
    at String.fromCodePoint (<anonymous>)
    at he (tailwindcss/dist/chunk-F4544Y4M.mjs:1:5381)
    at ot.markUsedVariable (tailwindcss/dist/chunk-F4544Y4M.mjs:1:7619)

Root Cause

The CSS unescape function (he/Se in the minified source) is called from markUsedVariable with an input that contains the Windows file path:

--projects-BISLiveDeployer\a901ff95-24db-4499-8289-fa2bd3ebc9be

The backslash before the UUID (\a901ff95...) is matched by the CSS escape regex /\([\dA-Fa-f]{1,6}[\t\n\f\r ]?|[\S\s])/g, capturing \a901ff (6 hex digits). This is then decoded as code point 0xa901ff = 11,076,095, which exceeds the maximum valid Unicode code point (0x10FFFF = 1,114,111), causing String.fromCodePoint() to throw.

Expected Behavior

Per the CSS Syntax spec (§4.3.8):

If the value is zero, or is for a surrogate, or is greater than the maximum allowed code point, return U+FFFD REPLACEMENT CHARACTER (�).

The unescape function should handle out-of-range code points gracefully instead of crashing.

Suggested Fix

// Before (crashes on invalid code points):
function he(t) {
  return t.replace(/\([\dA-Fa-f]{1,6}[\t\n\f\r ]?|[\S\s])/g,
    r => r.length > 2
      ? String.fromCodePoint(Number.parseInt(r.slice(1).trim(), 16))
      : r[1]
  );
}

// After (spec-compliant):
function he(t) {
  return t.replace(/\([\dA-Fa-f]{1,6}[\t\n\f\r ]?|[\S\s])/g, r => {
    if (r.length > 2) {
      let c = Number.parseInt(r.slice(1).trim(), 16);
      if (c > 0x10FFFF) return '\uFFFD';
      return String.fromCodePoint(c);
    }
    return r[1];
  });
}

However, there may also be a deeper issue: Windows backslash path separators should probably be normalized to forward slashes before being used as CSS identifiers.

Reproduction

  1. On Windows, create a project at a path where the directory name is followed by a folder/file with a hex-prefixed name (e.g. E:\projects\BISLiveDeployer\ with internal UUIDs like a901ff95-...)
  2. Set up Tailwind CSS v4 with @tailwindcss/vite
  3. Run vite build or vite dev

Environment

  • OS: Windows 11
  • Tailwind CSS: 4.1.18 (also reproduced on 4.2.2)
  • Vite: 6.4.1
  • @tailwindcss/vite: 4.1.18 (also reproduced on 4.2.2)
  • Node.js: v24.13.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions