Skip to content

fix(producer): guard fileServer.close in all render cleanup paths#1406

Open
calcarazgre646 wants to merge 2 commits into
heygen-com:mainfrom
calcarazgre646:fix/producer-fileserver-close-guard
Open

fix(producer): guard fileServer.close in all render cleanup paths#1406
calcarazgre646 wants to merge 2 commits into
heygen-com:mainfrom
calcarazgre646:fix/producer-fileserver-close-guard

Conversation

@calcarazgre646

@calcarazgre646 calcarazgre646 commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Problem

fileServer.close() is called bare (no try/catch) in several render cleanup paths. FileServerHandle.close tears down the underlying http.Server, whose close() throws ERR_SERVER_NOT_RUNNING if the server was already torn down (for example a cancellation path that already closed it once). An unguarded throw escapes the cleanup and masks the original plan/render result.

The immediately adjacent probe-session close already guards against exactly this, and its comment spells it out:

// Close inside a try/catch — leaking a Chrome process here would mask
// the original plan() result on cancellation paths.

The file-server closes next to it were left unguarded. There were three:

  • distributed/plan.ts (probe cleanup),
  • distributed/renderChunk.ts (finally block),
  • renderOrchestrator.ts (the in-process render success path, right before the assemble stage — a throw here would skip assembly and mask the result).

Fix

Add closeFileServerSafely(fileServer, label, log) in fileServer.ts, which wraps the close in a try/catch and logs, and route all three sites through it.

Tests

Unit tests for closeFileServerSafely: a throwing close() is swallowed and logged (does not propagate), and the happy path closes exactly once with no warning. plan test suite stays green. (The renderChunk byte-identical determinism test is host-Chrome dependent and soft-skips outside Dockerfile.test.)

`plan()` and `renderChunk()` both close the probe/chunk file server with a
bare `fileServer.close()` in their cleanup sequence. `FileServerHandle.close`
tears down the underlying http.Server, whose `close()` throws
`ERR_SERVER_NOT_RUNNING` if the server was already torn down (for example a
cancellation path that closed it once already). An unguarded throw there
escapes the cleanup and masks the original plan/render result, exactly the
failure the adjacent probe-session close already guards against with a
try/catch (its comment even spells this out).

Add `closeFileServerSafely`, which wraps the close in a try/catch and logs,
and route both cleanup sites through it so the two stay consistent and a
throwing close can never mask the real result. Covered by unit tests for
both the throwing and happy paths.
@calcarazgre646 calcarazgre646 changed the title fix(producer): guard fileServer.close in distributed cleanup paths fix(producer): guard fileServer.close in all render cleanup paths Jun 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant