Skip to content

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

@hisnameisjoel

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

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