aws-samples / aws-samples/sample-autonomous-cloud-coding-agents

fix(agent): unrunnable pipeline.buildCommand kills the task pre-agent while a build timeout degrades gracefully

Open
#750 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
143
Forks
46
Avg merge
3d 9h
Merged PRs (30d)
20

Description

### Component

Agent (Python runtime)

### Describe the bug

A `pipeline.buildCommand` whose executable does not exist in the agent container raises `FileNotFoundError` out of the pre-agent baseline build and **kills the task before the agent ever runs**. The surrounding code goes to considerable lengths to handle the analogous timeout case gracefully, so this looks like an oversight rather than a deliberate choice.

`agent/src/repo.py:457-473`:

```python
try:
result = run_cmd(build_argv, label="verify-build-pre", ..., timeout=BUILD_VERIFY_TIMEOUT_S, stream=True)
except subprocess.TimeoutExpired:
log("WARN", f"Initial build ({build_cmd_str}) did not finish within ... skipping baseline (not a regression)")
```

The comment above that block explains the reasoning for the timeout path at length — *"a timeout means 'no usable baseline', NOT 'the agent broke it', so we treat it as no-known-regression and let the run proceed"* — and notes that without the guard the task would "crash the whole task BEFORE the agent ever ran, so the issue got no PR and sat in Backlog — indistinguishable from a real failure."

A missing binary produces exactly that outcome, because only `TimeoutExpired` is caught.

### Expected behavior

An unrunnable build command should be treated the same way as a timeout: log a warning, record "no usable baseline", and let the agent run. The misconfiguration should be surfaced on the PR (and ideally as an inert-gate note), not converted into a task failure.

### Current behavior

The task dies during hydration with `build_passed=null` and no PR. Observed on task `01KZS2MS1BG7TDXHR7CDNMYM0A`:

```
status = FAILED
build_passed = null
error_message = FileNotFoundError: [Errno 2] No such file or directory: 'pytest'
```

Total time to failure: ~20 seconds. The agent never started, so a single typo in a blueprint's `buildCommand` bricks every task against that repo until someone redeploys.

### Reproduction steps

1. Onboard a repo with a `pipeline.buildCommand` naming a binary not present in the agent image, e.g. `buildCommand: 'pytest tests/unit/'` (the agent container's `PATH` leads with `/app/.venv/bin`, built `uv sync --frozen --no-dev` per `agent/Dockerfile:104`, so there is no `pytest`).
2. Submit any coding task against that repo.
3. Task fails in ~20s at hydration with the `FileNotFoundError` above; no PR, no agent turns.

### Possible solution

Catch `FileNotFoundError` (and likely `PermissionError`/`NotADirectoryError`) alongside `subprocess.TimeoutExpired` in both the pre-agent baseline (`agent/src/repo.py:457`) and the post-agent gate (`agent/src/post_hooks.py:187`), mapping them onto the existing inert-gate path rather than a task failure — an unrunnable command verified nothing, which is the definition of inert already handled elsewhere in `pipeline.py:1435-1441`.

Arguably a misconfigured blueprint should also surface a distinct, non-retryable error classification so the operator knows to fix the blueprint rather than retry.

Contributor guide

Open the contributing guide

Research direction

Start with the existing TimeoutExpired handling in agent/src/repo.py:457-473 and compare the post-agent gate in agent/src/post_hooks.py:187. Review the inert-gate behavior in pipeline.py:1435-1441, then verify that an unavailable build executable is logged as having no usable baseline, allows the agent to run, and is surfaced on the PR rather than failing the task.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
75/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.