fix(media): use r+ for Windows media fsync (#76593)

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>
This commit is contained in:
李claw
2026-05-05 08:58:31 +08:00
committed by GitHub
parent f7f5050252
commit 25db482cc6
2 changed files with 2 additions and 1 deletions

View File

@@ -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 `<media:image>`. 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.

View File

@@ -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 {