From 6891b00edad9526dc4bd786d34a3f38e0cd47581 Mon Sep 17 00:00:00 2001 From: Ethan Dickson Date: Thu, 18 Dec 2025 13:27:43 +1100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20fix:=20use=20atomic=20writes=20f?= =?UTF-8?q?or=20experiments=20cache?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test 'refreshExperiment updates cache and writes it to disk' was flaky because fs.writeFile is not atomic - it truncates the file before writing, creating a race window where readers can see an empty or partial file. Switch to write-file-atomic which writes to a temp file then renames, making the operation atomic. --- _Generated with `mux` • Model: `anthropic:claude-opus-4-5` • Thinking: `high`_ --- src/node/services/experimentsService.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/node/services/experimentsService.ts b/src/node/services/experimentsService.ts index 507661e0c2..9e52b7c116 100644 --- a/src/node/services/experimentsService.ts +++ b/src/node/services/experimentsService.ts @@ -4,7 +4,9 @@ import { getMuxHome } from "@/common/constants/paths"; import type { ExperimentValue } from "@/common/orpc/types"; import { log } from "@/node/services/log"; import type { TelemetryService } from "@/node/services/telemetryService"; + import * as fs from "fs/promises"; +import writeFileAtomic from "write-file-atomic"; import * as path from "path"; export type { ExperimentValue }; @@ -298,7 +300,7 @@ export class ExperimentsService { }; await fs.mkdir(this.muxHome, { recursive: true }); - await fs.writeFile(this.cacheFilePath, JSON.stringify(payload, null, 2), "utf-8"); + await writeFileAtomic(this.cacheFilePath, JSON.stringify(payload, null, 2), "utf-8"); } catch { // Ignore cache persistence failures }