Bug: Feishu image/media download fails with EPERM on Windows
Description
When a user sends an image (or other media) via Feishu, the plugin fails to download it on Windows with:
ERROR feishu - failed to download image media: Error: EPERM: operation not permitted, fsync
The data is successfully received from the Feishu API but the file never lands in the media/inbound/ directory. This affects any Windows-based OpenClaw Gateway running the Feishu plugin.
Root Cause (Two Independent EPERM Sources)
Source 1: @larksuiteoapi/node-sdk HTTP response writeFile() calls fsync internally
File: feishu plugin's send-*.js (hash varies per build in @openclaw/feishu/dist/)
The SDK's params.response.writeFile() method internally calls fsync on the file handle before closing. On Windows, this triggers EPERM: operation not permitted, fsync when the file descriptor was opened in read mode or when the filesystem/driver doesn't fully support fsync on certain handles.
Fix 1: Prioritize response.getReadableStream() over response.writeFile() to bypass the SDK's writeFile -> fsync path entirely:
// Before send-*.js (around the line "const { response } = params;"):
const { response } = params;
// ... SDK's writeFile is called which internally fsync
// After - add getReadableStream-first priority:
const { response } = params;
if (typeof response.getReadableStream === "function") {
try {
const result = await readReadableBuffer(response.getReadableStream());
return result;
} catch (e) {
// fall through to writeFile fallback
}
}
// ... existing writeFile path as fallback
Source 2: OpenClaw core writeSavedMediaBuffer calls handle.sync() on read-mode fd
File: openclaw/dist/store-*.js (hash varies per build)
After downloading media data, the core writeSavedMediaBuffer function writes the file using handle.writeFile(buffer) and then calls handle.sync() to ensure data durability. However, on Windows, calling fsync on a file opened for read (or on certain filesystems) raises EPERM. The data is already written by writeFile, so the fsync is a reliability optimization - not a correctness requirement.
Fix 2: Wrap handle.sync() in try/catch to suppress EPERM:
// Before:
try {
await handle.sync();
} finally {
await handle.close();
}
// After:
try {
await handle.sync();
} catch(err2) {
if (err2?.code === "EPERM") {
// fsync not supported on this platform/file handle, data already written by writeFile
// ignore EPERM, treat as success
} else throw err2;
} finally {
await handle.close();
}
Environment
- Windows (tested on Windows 11 24H2, NTFS)
- OpenClaw v2026.5.3-1
@openclaw/feishu plugin (any version using @larksuiteoapi/node-sdk)
- File system: NTFS
How to Reproduce
- Run OpenClaw Gateway on Windows
- Configure Feishu channel
- Send any image or media to the bot
- Check logs - you will see
EPERM: operation not permitted, fsync
- Check
media/inbound/ - file is missing, agent sees <media:image> but cannot process the image
Expected Behavior
Images/media should download successfully on Windows without EPERM errors. The agent should receive the actual file content.
Workaround
Both fixes can be applied manually as post-upgrade patches. See the _repatch_all.py script approach - find the two locations and apply the changes described above.
Related Issues
Files Affected
node_modules/@openclaw/feishu/dist/send-*.js (1 fix: getReadableStream-first priority)
openclaw/dist/store-*.js (1 fix: handle.sync() EPERM suppression)
Bug: Feishu image/media download fails with EPERM on Windows
Description
When a user sends an image (or other media) via Feishu, the plugin fails to download it on Windows with:
The data is successfully received from the Feishu API but the file never lands in the
media/inbound/directory. This affects any Windows-based OpenClaw Gateway running the Feishu plugin.Root Cause (Two Independent EPERM Sources)
Source 1:
@larksuiteoapi/node-sdkHTTP responsewriteFile()calls fsync internallyFile: feishu plugin's
send-*.js(hash varies per build in@openclaw/feishu/dist/)The SDK's
params.response.writeFile()method internally callsfsyncon the file handle before closing. On Windows, this triggersEPERM: operation not permitted, fsyncwhen the file descriptor was opened in read mode or when the filesystem/driver doesn't fully support fsync on certain handles.Fix 1: Prioritize
response.getReadableStream()overresponse.writeFile()to bypass the SDK's writeFile -> fsync path entirely:Source 2: OpenClaw core
writeSavedMediaBuffercallshandle.sync()on read-mode fdFile:
openclaw/dist/store-*.js(hash varies per build)After downloading media data, the core
writeSavedMediaBufferfunction writes the file usinghandle.writeFile(buffer)and then callshandle.sync()to ensure data durability. However, on Windows, callingfsyncon a file opened for read (or on certain filesystems) raisesEPERM. The data is already written bywriteFile, so the fsync is a reliability optimization - not a correctness requirement.Fix 2: Wrap
handle.sync()in try/catch to suppress EPERM:Environment
@openclaw/feishuplugin (any version using @larksuiteoapi/node-sdk)How to Reproduce
EPERM: operation not permitted, fsyncmedia/inbound/- file is missing, agent sees<media:image>but cannot process the imageExpected Behavior
Images/media should download successfully on Windows without EPERM errors. The agent should receive the actual file content.
Workaround
Both fixes can be applied manually as post-upgrade patches. See the
_repatch_all.pyscript approach - find the two locations and apply the changes described above.Related Issues
Files Affected
node_modules/@openclaw/feishu/dist/send-*.js(1 fix: getReadableStream-first priority)openclaw/dist/store-*.js(1 fix: handle.sync() EPERM suppression)