[Windows] fdatasyncSync on read-only fd throws EPERM, blocks node credential snapshot (canonicalIdentityLock.js)
Author: tree1961Created Sep 5, 2026Updated Sep 5, 2026
Summary
On Windows, src/canonicalIdentityLock.js opens the owner file in read-only mode and then calls fs.fdatasyncSync() on that descriptor. Windows' fdatasync (backed by FlushFileBuffers) requires a writable handle, so a read-only fd throws EPERM: operation not permitted, fdatasync. This breaks the canonical node-credential snapshot, so node registration / hello handshake cannot persist credentials.
Steps to reproduce
- On Windows, clone and
npm install. - Run
node index.js(or--loop). - Observe the non-fatal errors:
[a2aProtocol] Failed to snapshot canonical node credentials: EPERM
[TaskReceiver] Fetch/claim failed (non-fatal): EPERM: operation not permitted, fdatasyncMinimal repro:
const fs = require('fs');
fs.writeFileSync('x', 'hello');
const fd = fs.openSync('x', 'r'); // read-only
fs.fdatasyncSync(fd); // throws EPERM on WindowsRoot cause
src/canonicalIdentityLock.js, prepareOwnerFile():
descriptor = fs.openSync(preparedOwnerFile, 'r'); // read-only
fs.fdatasyncSync(descriptor); // EPERM on win32fdatasync on a read-only fd is tolerated on Linux/macOS but fails on Windows (FlushFileBuffers -> ERROR_ACCESS_DENIED -> EPERM).
Suggested fix
Open read+write so fdatasync has a writable handle:
descriptor = fs.openSync(preparedOwnerFile, 'r+');
fs.fdatasyncSync(descriptor);Environment
- OS: Windows (win32)
- Node.js: v22.22.2
- Evolver version: 1.94.0
Source: EvoMap/evolver