← 패치노트

수정 2026-10-16

v1.36.305

2026-10-16

핵심 변경

Fixed: on Windows with Node 23.x, 24.0.0-24.21.x, 25.x or 26.0.0-26.8.x, a removal that failed (a file or folder another process holds: an editor, antivirus, a shell's working directory) could end leerness without any error when the path had a character outside the system code page, and on other non-ASCII paths the error named a garbled path (T-0365). This is a Node bug: when fs.rmSync fails, Node builds the error from the absolute path given, converted with the ANSI code page, which ends the process for a character the code page cannot hold (exit code 0xC0000409; no try/catch sees it). Node fixed it in 24.22.0 and 26.9.0; 22.x and older are not affected. Measured on this PC (Node 26.3.0, code page 949): the process ended for e-acute, u-umlaut, n-tilde, Thai, Arabic, an emoji and a CJK Extension B character, and not for ASCII, Hangul, hanja, kana, Cyrillic, Greek, the euro sign or the other characters code page 949 holds; also for a single held file; read-only files are removed normally.
Tests: scripts/safe-remove-probe.js (new, in npm run test:temp-cleanup), twenty-nine cases: the version bounds on Windows, Linux and macOS; which paths are isolated (ASCII paths are not; relative, Buffer and Hangul paths); without the isolate option an ASCII path is exactly one fs.rmSync call and a non-ASCII one is isolated only with the bug; where it is off, removeSync is exactly one fs.rmSync call with the same arguments; a full folder goes to the child as the absolute path this process resolved, also for a drive-relative D:rel, with the four option values it uses; bad options are rejected before anything is removed, with fs.rmSync's error; options are read as Node reads them (an inherited or non-enumerable recursive does not count; a BigInt extra, a cycle or a toJSON changes nothing; each option is read once, as by fs.rmSync, getters included); the child removes a relative path from this working directory and runs without NODE_OPTIONS; an empty path removes nothing, as fs.rmSync; under --dry-run the removal is refused at the folder, also when it is spelled with a trailing separator or given as a URL with a search part, and nothing inside goes, and where the guard allows the folder (a *.lock folder) all of it goes, as with fs.rmSync (where fs.rmSync is native and asks the guard once; on Node 22 and older it asks for each entry, and the case says so and is skipped); a nested tree with a read-only file and non-ASCII names is removed; links are removed as links and their targets kept; the same results as fs.rmSync for a missing path (with and without force), a folder without recursive, a file, an empty folder and a full folder; this process never calls fs.rmSync on the target of an isolated removal; a failure names the target with its code, and a child ended by the bug is an EPERM error; a held file is waited out with maxRetries; the removal sites use removeSync; on Windows, leerness skill remove with a held folder under a path with an emoji ends with an error, the npm temp cleanup reports the folder as not cleaned, and removeTree fails with the code and waits out a short hold, instead of the process ending; the env flag and the advisory in English and Korean; selftest prints the advisory in the language chosen with LEERNESS_LANG; the selftest case. On this PC the probe's first version passed 0 of 15 cases on the 1.36.304 code, and with lib/ switched but bin/ and scripts/ not, the three Windows cases ended the process (0xC0000409). selftest has one more case. scripts/test-node-runner-probe.js injects its fixture hold into rmdirSync as well; scripts/temp-cleanup-probe.js skips its direct fs.rmSync report on an affected Node with a non-ASCII temp path.

GitHub 릴리스 v1.36.305 →