commit b6271af73b248b63f51d33585346562f95f5ebe6
parent f6a1108d4804a421618645629ab93b55b095e78a
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Fri, 25 Sep 2026 00:28:31 -0400
common: the remote transcript is written with writeFileAtomic
transcribeOne's upload path wrote the pulled bytes straight onto
transcript.json with fs-extra's writeFile — no temp file, so a crash
mid-write left a truncated transcript for the indexer. It now goes
through `writeFileAtomic` (lib/jsonFile-server.ts), the one tmp+rename
idiom slice W folded every other writer onto. The shared-fs path is
unchanged (the remote writes the file itself).
No new test: the remote path needs a live remote worker and this
codebase does not module-mock; the idiom has its own tests.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/common/controller/transcribeOne.ts b/common/controller/transcribeOne.ts
@@ -16,8 +16,9 @@ import { findSourceMedia, isRealAudioFile } from "../lib/videoStatus";
import { pickPreferredAudio } from "../lib/mediaFiles";
import { resolveSavedVideo } from "../lib/savedVideo-server";
import { writeTranscribeOutcome } from "../lib/transcribeOutcome-server";
+import { writeFileAtomic } from "../lib/jsonFile-server";
-const { pathExists, readdir, rename, writeFile } = fs;
+const { pathExists, readdir, rename } = fs;
async function resolveAudioFile(
videoDir: string,
@@ -168,9 +169,11 @@ export async function transcribeOneVideo(
await throwIfAudioVanished(opts.videoDir, resolvedAudio, opts.videoId);
throw err;
}
- // Upload path: write the pulled bytes. Shared-fs path (bytes === null): the
- // remote already wrote transcript.json onto the shared mount at this path.
- if (bytes) await writeFile(transcriptPath, bytes);
+ // Upload path: write the pulled bytes — atomically, so a crash mid-write
+ // never leaves a truncated transcript.json for the indexer to read. Shared-fs
+ // path (bytes === null): the remote already wrote transcript.json onto the
+ // shared mount at this path.
+ if (bytes) await writeFileAtomic(transcriptPath, bytes);
// The remote didn't tell us the engine format; sniff it from the file (the
// same content sniff the indexer uses for mixed corpora).
const raw = await fs.readFile(transcriptPath, "utf8").catch(() => "");