Summary
_publish_trajectory_for_verifier gates a mkdir -p /logs/agent at a hardcoded
timeout_sec=10. When that exec exceeds 10s on a loaded host, the exception
propagates and the whole rollout is lost — after the agent ran to completion.
https://github.com/benchflow-ai/benchflow/blob/main/benchflow/rollout/_setup.py#L440 (v0.6.6; same call at _setup.py:418 in v0.6.5)
await env.exec("mkdir -p /logs/agent", user="root", timeout_sec=10)
The command is trivial, but the exec is not: on a busy host, Docker exec setup
alone can exceed 10s. The asymmetry is what makes it expensive — a ~40 minute
rollout is discarded by a 10 second budget on a bookkeeping step, after all the
costly work has already succeeded.
Impact
Seen in a 16-launch replication series where the task under test is itself
I/O-heavy (an AFL++ campaign with ~20 parallel workers saturating disk). One
launch died this way:
RuntimeError: Command timed out after 10 seconds
on mkdir -p /logs/agent during trajectory publish, on the third internal
attempt (the first two had failed for unrelated transient reasons). It had to be
excluded from the experiment's denominators entirely — it is the only launch in
the series we could not classify as either a success or a genuine agent-side
failure, because the failure is purely in publishing.
Environment: benchflow 0.6.5 and 0.6.6, Docker sandbox, Linux.
Why this looks like a bug rather than a tight-but-intentional budget
On the Docker backend specifically, the exec appears to be doing no work.
_publish_trajectory_for_verifier calls agent_dir.mkdir(parents=True, exist_ok=True)
two lines above, and per the function's own docstring Docker bind-mounts
/logs/agent to that same host dir — so the directory already exists by the time
the container-side mkdir -p runs. The call is defensive for backends that
don't mirror (Daytona, Modal), but on Docker it can only fail, never help.
The await env.upload_file(...) immediately after would fail loudly on its own
if the directory genuinely were missing, so the mkdir failing fatally is not
load-bearing for correctness.
Suggested fix
In rough preference order:
- Make the
mkdir non-fatal — wrap in contextlib.suppress(Exception) (or
retry once) and let the subsequent upload_file be the real error surface.
- Retry the publish-path execs before failing the rollout.
- Make the timeout configurable, or scale it with the configured agent timeout,
rather than fixing it at 10s.
Happy to send a PR for (1) if that's the direction you'd prefer.
Summary
_publish_trajectory_for_verifiergates amkdir -p /logs/agentat a hardcodedtimeout_sec=10. When that exec exceeds 10s on a loaded host, the exceptionpropagates and the whole rollout is lost — after the agent ran to completion.
https://github.com/benchflow-ai/benchflow/blob/main/benchflow/rollout/_setup.py#L440 (v0.6.6; same call at
_setup.py:418in v0.6.5)The command is trivial, but the exec is not: on a busy host, Docker exec setup
alone can exceed 10s. The asymmetry is what makes it expensive — a ~40 minute
rollout is discarded by a 10 second budget on a bookkeeping step, after all the
costly work has already succeeded.
Impact
Seen in a 16-launch replication series where the task under test is itself
I/O-heavy (an AFL++ campaign with ~20 parallel workers saturating disk). One
launch died this way:
on
mkdir -p /logs/agentduring trajectory publish, on the third internalattempt (the first two had failed for unrelated transient reasons). It had to be
excluded from the experiment's denominators entirely — it is the only launch in
the series we could not classify as either a success or a genuine agent-side
failure, because the failure is purely in publishing.
Environment: benchflow 0.6.5 and 0.6.6, Docker sandbox, Linux.
Why this looks like a bug rather than a tight-but-intentional budget
On the Docker backend specifically, the exec appears to be doing no work.
_publish_trajectory_for_verifiercallsagent_dir.mkdir(parents=True, exist_ok=True)two lines above, and per the function's own docstring Docker bind-mounts
/logs/agentto that same host dir — so the directory already exists by the timethe container-side
mkdir -pruns. The call is defensive for backends thatdon't mirror (Daytona, Modal), but on Docker it can only fail, never help.
The
await env.upload_file(...)immediately after would fail loudly on its ownif the directory genuinely were missing, so the
mkdirfailing fatally is notload-bearing for correctness.
Suggested fix
In rough preference order:
mkdirnon-fatal — wrap incontextlib.suppress(Exception)(orretry once) and let the subsequent
upload_filebe the real error surface.rather than fixing it at 10s.
Happy to send a PR for (1) if that's the direction you'd prefer.