Skip to content

[Bug] Invalid code point crash on Windows when oxide scanner picks up runtime path+UUID identifiers #19786

Description

@hisnameisjoel

What version of Tailwind CSS are you using?

v4.1.12 (also confirmed present in v4.2.1 — not fixed)

What build tool (or framework if it abstracts the build tool) are you using?

@tailwindcss/vite 4.1.12, Vite 7.1.2, Tauri 2.x

What version of Node.js are you using?

v22.18.0

What browser are you using?

N/A (desktop app via Tauri webview)

What operating system are you using?

Windows 11

Reproduction URL

No minimal repo available, but the crash is fully deterministic on any Tailwind v4 + Vite + Tauri project on Windows. The trigger is Tauri's dev server injecting a runtime script containing a Windows path+UUID string that the oxide scanner picks up as a CSS candidate. The UUID happened to begin with hex digits — the Windows backslash path separator before it causes ge() to parse \d88195 as a 6-digit CSS hex escape evaluating to 0xD88195 = 14188949, which exceeds the maximum valid Unicode code point 0x10FFFF.

Describe your issue

On Windows, running vite dev (via Tauri) throws:

[plugin:@tailwindcss/vite:generate:serve] Invalid code point 14188949
at Function.fromCodePoint ()
at ge (tailwindcss/dist/chunk-.mjs)
at Be.markUsedVariable (tailwindcss/dist/chunk-.mjs)

The oxide scanner picks up a token from a Tauri-injected runtime script that looks like:

--Coding-Projects-CharacterMapper-Master-Workspace\d8819554-4725-4235-9d22-2d0ed572e924

Because it starts with --, the build loop passes it to markUsedVariable(), which calls ge() to unescape it. The ge() regex matches \d88195 (Windows path backslash + first 6 hex digits of the UUID) as a CSS hex escape, computes parseInt("d88195", 16) = 14188949, and String.fromCodePoint(14188949) throws.

Expected behavior: Per the CSS spec, out-of-range code points should substitute U+FFFD rather than throw. The ge() function should add a bounds check before calling String.fromCodePoint().

Workaround: Adding @source "../src/**/*.{ts,tsx,html}" to the main CSS file restricts the oxide scanner to actual source files and prevents it from encountering the injected string.

Note: This appears to be the same class of bug as #18734 (binary .hdr files being scanned). That PR fixed the scanner side; this suggests also fixing ge() defensively so any out-of-range escape — regardless of source — doesn't crash the build.

Metadata

Metadata

Assignees

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