Skip to content

Flaky test: sandbox-orphan-reaping "bounds a hung removal" wall-clock bound (< 6500 ms) exceeded under load #3879

Open

Description

@acoliver

packages/cli/src/utils/sandbox-orphan-reaping.bun.test.ts, case "sandbox orphan recovery startup > bounds a hung removal and continues processing other orphans", fails intermittently on macOS (Apple Silicon, Bun 1.3.14). The assertion at line 807 checks elapsed wall-clock time:

expect(received).toBeLessThan(expected)
Expected: < 6500
Received: 6930

How often it fails:

The test measures how long recovery takes when one container removal hangs, and checks the total against a fixed wall-clock limit. On a loaded machine, the bounded removal timeout plus the processing of the remaining orphans can exceed 6.5 s even when the hung removal is cut off correctly.

Suggested fix: assert on the recovery sequence rather than elapsed real time. For example, check that the hung removal was abandoned at its bound, that the remaining orphans were processed afterwards, and that startup continued. Alternatively, drive the timeout from an injected clock, so the bound is verified without depending on scheduler latency.

Activity

  1. acoliver commented on Oct 16, 2026

    @acoliver
    CollaboratorAuthor

    A second failure mode in the same file. In 8 standalone runs (bun test --timeout 60000 ./src/utils/sandbox-orphan-reaping.bun.test.ts, machine load average about 35-45), 7 passed 23/23. The other failed in "records and retains matching owners under a non-UTC host timezone" after 30.5 s:

    error: spawnSync /opt/homebrew/Cellar/bun/1.3.14/bin/bun ETIMEDOUT
      spawnargs: ["test", "--timeout", "30000", ".../sandbox-orphan-reaping.bun.test.ts",
                  "--test-name-pattern", "records and retains matching owners under a non-UTC host timezone"]
      at rerunInNonUtcTimezone (sandbox-orphan-reaping.bun.test.ts:247)
    

    rerunInNonUtcTimezone re-runs the test file in a child bun test process under a different TZ, using spawnSync with a 30 s timeout. A cold Bun start, plus that file's module graph and the case itself, can take longer than 30 s on a loaded machine. When it does, the parent fails with ETIMEDOUT, whatever the timezone behaviour is.

    A possible fix is to run the timezone-sensitive code in-process with an injected timezone or clock. If the child process stays, have it import only the code under test, and give it a budget derived from the parent test timeout rather than a separate fixed 30 s.

  2. github-actions commented on Oct 16, 2026

    @github-actions
    Contributor

    LLxprt Issue Planner — infrastructure failure

    The autonomous planner failed with exit code 1. Please inspect the workflow logs (Run planner agent section) and re-run once resolved.

  3. acoliver commented on Oct 16, 2026

    @acoliver
    CollaboratorAuthor

    A third failure mode in the same file, which depends on test order rather than on a fixed wall-clock bound.

    The case is "sandbox orphan recovery startup > applies the same dead-owner recovery through Podman" (line 655). The dead owner's row is kept in the Podman state file instead of being removed:

    -   "state": "",
    +   "state": "podman-orphan\t{\"version\":1,...,\"pid\":30090,...,\"startTimeSource\":\"observed\"}\n",
    

    What I measured on 2026-10-16, at a machine load average of about 40 to 46:

    Commit Run Result
    f8b8cae whole file, 3 runs failed 3/3 (one run also failed "removes a reused-PID container without terminating the live process" at line 585)
    f8b8cae this case only (-t), 2 runs passed 2/2, 1.1 s and 2.2 s
    f55fc2e this case only (-t), 2 runs passed 2/2, 1.1 s and 1.6 s
    f55fc2e whole file, 2 runs failed 2/2

    f55fc2e passed the whole CLI suite, including this file, in a full run about 90 minutes before these measurements. The two commits do not differ in the sandbox files.

    So the case fails only after earlier cases in the same file have run, and only in the machine state at the time. The failing runs take 5.7 to 7.3 s, close to the "bounds a hung engine listing" case (about 5.1 s). That suggests the Podman listing in this case hits its 5 s bound, possibly because a hung-listing fixture or child process from an earlier case is still running, and recovery then keeps the row.

    Suggested fix: make each case fully reap the fixture processes it starts, and give each case its own engine state and fixture directories, so that hung-listing and hung-removal cases cannot affect later ones. Logs are in the integration worktree under tmp/verify-int/full78/rerun-orphan*.log and in the scratch worktree under tmp/orphan/.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions