fix(extract): finalize detached runs that extract artifacts#17
Merged
Conversation
A detached run with `extract` never finalized. extractFromVolume's seeder container used AutoRemove and waited on the hijacked attach stream closing, which a volume-bound container does not reliably emit on Docker Desktop / Windows. The run hung forever in `running`, its container and volume were never cleaned up, and any caller polling the run state (light-run, and through it light-process) looped indefinitely - so every light-process node run hung. - seeder: AutoRemove off; wait for the seeder to exit via inspect() polling (awaitSeederExit, the same race-free approach the detached run path already uses), drain the final bytes on an idle timeout (drainIdle) instead of on stream close, and remove the container explicitly - extract: runAlpine and streamTarOut use the new lifecycle with a finally that always removes the seeder - listStates: skip sibling files in the state dir that have no id (e.g. cache-usage.json), which made listing runs throw path.join(undefined) build with cc
enixCode
added a commit
that referenced
this pull request
Jun 2, 2026
Release 0.16.2. Ships the detached-extract finalize fix (#17). - package.json + lock: 0.16.1 -> 0.16.2 - telemetry.ts: TRACER_VERSION 0.16.1 -> 0.16.2 (lock-step) build with cc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A detached run with
extractnever finalized.extractFromVolume's seeder container usedAutoRemoveand waited on the hijacked attach stream closing, which a volume-bound container does not reliably emit on Docker Desktop / Windows. The run hung forever inrunning, its container and volume were never cleaned up, and any caller polling the run state (light-run, and through it light-process) looped indefinitely. Every light-process node run hung.Root cause
The extract seeder relied on the hijacked attach stream emitting
end/closeto know tar had finished. Volume-boundAutoRemovecontainers do not reliably emit those events on some Docker builds (the write path already documents this and moved toputArchive; the read/extract path still relied on stream close).Fix
AutoRemoveoff; wait for the seeder to exit viainspect()polling (awaitSeederExit, the same race-free approach the detached run path already uses), drain the final bytes on an idle timeout (drainIdle) instead of on stream close, and remove the container explicitly (removeSeeder).runAlpineandstreamTarOutuse the new lifecycle with afinallythat always removes the seeder.id(e.g.cache-usage.json), which made listing runs throwpath.join(undefined)(HTTP 500 onGET /runs).Verification
volume/extracte2e (incl. a 5 MB file), detached e2e.DockerRunner.rundetached+extract returns{ success: true, extracted: [{ status: 'ok', bytes: ... }] }.build with cc