Skip to content

fix(eval): reap orphaned eval containers on context cancellation#3586

Draft
aheritier wants to merge 1 commit into
mainfrom
fix/3585-reap-orphaned-eval-containers
Draft

fix(eval): reap orphaned eval containers on context cancellation#3586
aheritier wants to merge 1 commit into
mainfrom
fix/3585-reap-orphaned-eval-containers

Conversation

@aheritier

Copy link
Copy Markdown
Contributor

Summary

Fixes #3585. When a docker agent eval run is cancelled (timeout, Ctrl-C, or a per-eval failure cancelling the parent context), the per-eval containers launched with --rm were orphaned rather than reaped. exec.CommandContext kills the docker CLI process on cancellation but never signals the container it started, so --rm cleanup never fires — leaving long-lived containers (observed 40+ min, runaway filesystem walks).

Changes

  • Core fix: added reapContainer, deferred immediately after cmd.Start() in runDockerAgentInContainer, which force-removes the container via docker rm -f <name> on a fresh, detached context (so it runs even when the eval context is already cancelled). Respects --keep-containers and treats No such container as benign (the normal --rm happy path).
  • Stderr race fix: replaced StderrPipe + background io.ReadAll goroutine with cmd.Stderr = &bytes.Buffer{}, eliminating a pre-existing data race and the incorrect Wait-before-drain ordering by construction. Added cmd.WaitDelay = 10s hardening.
  • Tests: 5 daemon-free integration tests through runDockerAgentInContainer (fake docker on PATH distinguishing run/rm) covering caller-context cancellation, non-zero exit, scanner token-too-long, normal success, and --keep-containers skipping cleanup. Verified the regression is caught — removing the defer fails 4 of 5.
  • Docs: documented cleanup-on-cancellation behavior in docs/features/evaluation/index.md and docs/features/cli/index.md.

Validation

  • task build / task test / task lint — all clean
  • go test -race ./pkg/evaluation — clean

Fixes #3585

exec.CommandContext only kills the docker CLI on ctx cancellation; the
container it launched keeps running and --rm never fires, leaking
long-lived eval containers (see #3585). Add a deferred reapContainer
that force-removes the container on a fresh, detached context,
respecting --keep-containers, and treats 'No such container' as benign.

Also assign a bytes.Buffer to cmd.Stderr instead of using StderrPipe
with a background goroutine, fixing a stderr data race and the incorrect
Wait-before-pipe-drain ordering by construction.

Adds daemon-free integration tests through runDockerAgentInContainer
that protect the cleanup regression, and documents the behavior.

Fixes #3585
@aheritier aheritier force-pushed the fix/3585-reap-orphaned-eval-containers branch from 16ba3cf to 219e8ce Compare July 11, 2026 05:11
@aheritier aheritier added area/docs Documentation changes area/testing Test infrastructure, CI/CD, test runners, evaluation kind/fix PR fixes a bug (maps to fix:). Use on PRs only. labels Jul 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docs Documentation changes area/testing Test infrastructure, CI/CD, test runners, evaluation kind/fix PR fixes a bug (maps to fix:). Use on PRs only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

eval: cancelled/interrupted runs orphan --rm eval containers (never reaped)

1 participant