From eef469075299439c0c79b38d8488639106a42dca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miguel=20=C3=81ngel?= Date: Thu, 2 Jul 2026 17:45:16 -0700 Subject: [PATCH] fix(engine): name the fix in the ffmpeg encode-timeout error message (#1858) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two independent post-release feedback reports of hitting ffmpegEncodeTimeout (600000ms default) on long or high-frame-count renders, both resolved by setting FFMPEG_ENCODE_TIMEOUT_MS to a higher value and/or PRODUCER_ENABLE_CHUNKED_ENCODE=true — env vars that already exist and already solve this, but that neither user found from the error message itself. appendEncodeTimeoutMessage only stated what happened ("FFmpeg killed after exceeding ffmpegEncodeTimeout"), not what to do about it. Name both existing knobs in the message so the fix is immediately visible at the point of failure instead of requiring a source dive. One function, six call sites, all fixed at once. Existing tests assert with toContain, so the appended text doesn't break them; added two assertions confirming both env var names appear in the message. --- packages/engine/src/services/chunkEncoder.test.ts | 5 +++++ packages/engine/src/services/chunkEncoder.ts | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/engine/src/services/chunkEncoder.test.ts b/packages/engine/src/services/chunkEncoder.test.ts index d97c3939e..4014afd38 100644 --- a/packages/engine/src/services/chunkEncoder.test.ts +++ b/packages/engine/src/services/chunkEncoder.test.ts @@ -154,6 +154,11 @@ describe("encodeFramesFromDir ffmpegEncodeTimeout", () => { expect(result.error).toContain("FFmpeg exited with code 143"); expect(result.error).toContain("terminated by timeout"); expect(result.error).toContain(encodeTimeoutMessage(1000)); + // Regression: the timeout message used to just state what happened, leaving + // the user to independently discover FFMPEG_ENCODE_TIMEOUT_MS and + // PRODUCER_ENABLE_CHUNKED_ENCODE (both already existed) on their own. + expect(result.error).toContain("FFMPEG_ENCODE_TIMEOUT_MS"); + expect(result.error).toContain("PRODUCER_ENABLE_CHUNKED_ENCODE"); }); it("keeps non-timeout ffmpeg failures unchanged", async () => { diff --git a/packages/engine/src/services/chunkEncoder.ts b/packages/engine/src/services/chunkEncoder.ts index 060e69aa7..44f3e68ab 100644 --- a/packages/engine/src/services/chunkEncoder.ts +++ b/packages/engine/src/services/chunkEncoder.ts @@ -44,7 +44,17 @@ export interface EncoderPreset { function appendEncodeTimeoutMessage(error: string, timedOut: boolean, timeoutMs: number): string { if (!timedOut) return error; - return `${error}\nFFmpeg killed after exceeding ffmpegEncodeTimeout (${timeoutMs} ms)`; + // Two independent reports of this exact timeout, both resolved by env vars + // that already exist but aren't named anywhere the user would see them at + // the point of failure — they had to go find FFMPEG_ENCODE_TIMEOUT_MS and + // PRODUCER_ENABLE_CHUNKED_ENCODE themselves. Name both here instead of + // just stating what happened. + return ( + `${error}\nFFmpeg killed after exceeding ffmpegEncodeTimeout (${timeoutMs} ms). ` + + "Long or high-frame-count renders may need more time: set FFMPEG_ENCODE_TIMEOUT_MS " + + "to a higher value (ms), or set PRODUCER_ENABLE_CHUNKED_ENCODE=true to encode in " + + "smaller chunks instead of one long-running ffmpeg process." + ); } function isAacSidecar(audioPath: string): boolean {