From 25db482cc6513efae2cc8e0e4a059c7ed289be8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8Eclaw?= Date: Tue, 5 May 2026 08:58:31 +0800 Subject: [PATCH] fix(media): use r+ for Windows media fsync (#76593) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix Windows media offload failures by opening saved attachment temp files read/write before fsync, preserving the non-truncating temp-file write path while allowing Windows FlushFileBuffers to succeed. Also adds the required changelog entry. Tests: - pnpm test src/media/store.test.ts src/gateway/chat-attachments.test.ts - pnpm check:changed Thanks @qq230849622-a11y. Co-authored-by: 李claw <264894741+qq230849622-a11y@users.noreply.github.com> Co-authored-by: Brad Groux <3053586+BradGroux@users.noreply.github.com> --- CHANGELOG.md | 1 + src/media/store.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 855006ad42d..ffc1d71285a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -62,6 +62,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Media/Windows: open saved attachment temp files read/write before fsync so Windows WebChat and `chat.send` media offloads no longer fail with EPERM during durability flush. (#76593) Thanks @qq230849622-a11y. - Codex plugin: mirror the experimental upstream app-server protocol and format generated TypeScript before drift checks, keeping OpenClaw's `experimentalApi` bridge compatible with latest Codex while preserving formatter gates. - Telegram/media: derive no-caption inbound media placeholders from saved MIME metadata instead of the Telegram `photo` shape, so non-image and mixed attachments no longer reach the model as ``. Fixes #69793. Thanks @aspalagin. - Agents/cache: keep per-turn runtime context out of ordinary chat system prompts while still delivering hidden current-turn context, restoring prompt-cache reuse on chat continuations. Fixes #77431. Thanks @Udjin79. diff --git a/src/media/store.ts b/src/media/store.ts index e1086921349..0aeb949c30a 100644 --- a/src/media/store.ts +++ b/src/media/store.ts @@ -349,7 +349,7 @@ async function writeSavedMediaBuffer(params: { const tempDest = path.join(params.dir, `.${params.id}.${crypto.randomUUID()}.tmp`); try { await fs.writeFile(tempDest, params.buffer, { mode: MEDIA_FILE_MODE }); - const handle = await fs.open(tempDest, "r"); + const handle = await fs.open(tempDest, "r+"); try { await syncSavedMediaHandle(handle); } finally {