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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions