From c69d6bd964019c2e254a838aa96562aab483e8d3 Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Fri, 8 May 2026 14:05:46 +0900 Subject: [PATCH] fix(team-mode): tolerate EPERM during fsync in atomicWrite and acquireLock Replaces direct fileHandle.sync() calls in acquireLock and atomicWrite with tolerantFsync. Users on iCloud Drive / OneDrive / Desktop sync folders were hitting 'EPERM: operation not permitted, fsync' during team_create, which propagated up and aborted the entire team_create flow even though the actual write+rename had succeeded. Reported on Discord (omo 4.0.0, opencode desktop 1.14.41, project on synced Desktop). atomicity is preserved by the temp-file rename; only the durability hint is now best-effort on filesystems that disallow fsync. --- src/features/team-mode/team-state-store/locks.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/features/team-mode/team-state-store/locks.ts b/src/features/team-mode/team-state-store/locks.ts index 0fca98494..2f7a4d4a0 100644 --- a/src/features/team-mode/team-state-store/locks.ts +++ b/src/features/team-mode/team-state-store/locks.ts @@ -1,6 +1,8 @@ import { randomUUID } from "node:crypto" import { open, readFile, rename, rm, unlink, writeFile } from "node:fs/promises" +import { tolerantFsync } from "../../../shared/tolerant-fsync" + type LockOptions = { staleAfterMs?: number ownerTag?: string @@ -51,7 +53,7 @@ async function acquireLock(lockPath: string, ownerTag: string, staleAfterMs: num const fileHandle = await open(lockPath, "wx") try { await fileHandle.writeFile(buildOwnerContent(ownerTag)) - await fileHandle.sync() + await tolerantFsync(fileHandle, `acquireLock:${lockPath}`) } finally { await fileHandle.close() } @@ -116,7 +118,7 @@ export async function atomicWrite( await writeFile(tmpPath, content) const fileHandle = await open(tmpPath, "r") try { - await fileHandle.sync() + await tolerantFsync(fileHandle, `atomicWrite:${filePath}`) } finally { await fileHandle.close() }