Skip to content

test(runtime): sandbox boundary request wait has no time budget and flakes on CI #4383

Description

@Astro-Han

Problem

The test job on main failed at 6b53667 with a single test failure in packages/runtime:

https://github.com/apache/maka/actions/runs/33407294088

packages/runtime/src/__tests__/tool-runtime-sandbox-boundary.test.ts:359
✖ canonicalizes filesystem authority before creating durable pending state
  Error: Sandbox boundary request was not emitted
      at waitForBoundaryRequest (packages/runtime/dist/__tests__/tool-runtime-sandbox-boundary.test.js:1007:11)

The failure is in the test's wait strategy, not in the code under test. waitForBoundaryRequest (same file, lines 1077-1086) polls the collected event array for a fixed count of macrotask ticks:

for (let attempt = 0; attempt < 100; attempt += 1) {
  const event = events.find((candidate) => candidate.type === 'sandbox_boundary_request');
  if (event?.type === 'sandbox_boundary_request') return event;
  await new Promise((resolve) => setTimeout(resolve, 0));
}
throw new Error('Sandbox boundary request was not emitted');

100 ticks is not a time budget. This particular case performs real filesystem work first — mkdtemp, mkdir, writeFile, symlink, realpath — and only canonicalizes and emits sandbox_boundary_request afterwards. On a loaded CI runner that IO spans far more ticks than it does locally, so the helper gives up before the event arrives. The same helper is used by three cases in the file, so any of them can fail this way.

The failing commit (#4286, provider reasoning replay) does not touch sandbox boundaries, and the neighbouring main runs for #4323, #4356, and #3129 all passed, which is consistent with load-dependent flakiness rather than a regression.

Desired outcome

waitForBoundaryRequest waits on an explicit deadline instead of a tick count, so the test fails only when the request is genuinely never emitted. Either is fine:

  • poll until a wall-clock deadline (a few seconds) with a small interval, or
  • have the test eventSink.push resolve a promise for the first sandbox_boundary_request, removing the polling loop entirely.

Production behavior must stay unchanged; this is test-infrastructure only.

Alternatives or workarounds

Re-running the job usually passes, but that hides a genuine loss of signal: the current failure message cannot distinguish "the runtime never emitted the request" from "the runner was slow".


Automated disclosure: this issue was drafted by Claude at @Astro-Han's direction. @Astro-Han remains the human contributor of record.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinggood first issueGood for newcomershelp wantedExtra attention is needed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions