Skip to content

bug(install): Windows postinstall EPERM cleaning up Go modcache — rm() missing maxRetries #1452

Description

@LucianoSantillan

Summary

On Windows, npm install -g gentle-pi@3.7.0 reliably fails during the package-local Gentle AI install step, even with no antivirus interference and a valid Go toolchain (go1.26.5) installed. The Windows path builds Gentle AI from source via the Go SumDB source-build method, then fails to clean up its own scoped GOMODCACHE.

Root cause

scripts/gentle-ai-installer.mjs line 328 sets a scoped Go environment per build:

GOBIN: join(buildDirectory, "gobin"), GOPATH: join(buildDirectory, "gopath"),
GOMODCACHE: join(buildDirectory, "gomodcache"), GOCACHE: join(buildDirectory, "gocache"),

go mod download / go build write files into GOMODCACHE as read-only by design (this is intentional, standard Go behavior — module cache files/dirs are marked read-only so they can't be accidentally modified).

The cleanup helper (safeRemoveDirectory, ~line 405) calls:

await rm(path, { recursive: true, force: true });

with no maxRetries/retryDelay. On Windows, Node's fs.rm only clears the read-only attribute and retries the unlink when maxRetries > 0. With the default (maxRetries: 0), a read-only file under the modcache tree causes a permanent EPERM: operation not permitted, rmdir/unlink '...gomodcache\...' — the build itself succeeds, but the mandatory cleanup step throws, and the whole postinstall (and therefore the whole npm install -g gentle-pi) fails and gets rolled back by npm.

This is 100% reproducible on a clean Windows machine (Windows 11, Go 1.26.5, Node 20.19.5, npm 10.8.2), independent of antivirus — confirmed by adding a full Windows Defender exclusion on %APPDATA%\npm and retrying, which changed nothing (the failure point moved from an unrelated Defender race on gentle-ai.exe to this modcache cleanup, and then stayed here on every subsequent attempt).

Repro

npm install -g gentle-pi

Fails every time with e.g.:

npm error gentle-pi could not install its package-local Gentle AI v3.7.0 binary: EPERM: operation not permitted, rmdir 'C:\Users\<user>\AppData\Roaming\npm\node_modules\gentle-pi\.gentle-ai\.v3.7.0.staging-XXXXXX\.build\gomodcache\golang.org\x\sys@v0.47.0\execabs'

(the exact path/module varies run to run, since it's whichever readonly file/dir the recursive rm hits first).

Suggested fix

Pass Windows-safe retry options to the cleanup rm() call(s), e.g.:

await rm(path, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });

or explicitly chmod/clear the read-only attribute recursively before removal on win32.

Workaround used

GENTLE_PI_SKIP_GENTLE_AI_INSTALL=1 npm install -g gentle-pi installs the JS package fine and skips the broken native build (with the documented tradeoff that native review operations report package-local-binary-missing).

Environment

  • OS: Windows 11 Pro
  • Go: go1.26.5 windows/amd64
  • Node: v20.19.5
  • npm: 10.8.2
  • gentle-pi: 3.7.0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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