Skip to content

fix(nighthawk): use pkill -f to stop sandbox server, prevent agent self-termination#79

Merged
studert merged 2 commits into
mainfrom
worktree-fix-automation
May 4, 2026
Merged

fix(nighthawk): use pkill -f to stop sandbox server, prevent agent self-termination#79
studert merged 2 commits into
mainfrom
worktree-fix-automation

Conversation

@studert
Copy link
Copy Markdown
Member

@studert studert commented May 4, 2026

Summary

The nighthawk workflow was failing with ##[error]Process completed with exit code 143 whenever the agent reached Step 10 or Step 11 and tried to stop the local Next.js sandbox server.

Root cause (from job 25277965317, step 23):

  1. Agent ran the prompt's snippet kill -TERM \$(cat server.pid) ... && sleep 2 && : > server.log && echo "Server stopped".
  2. Claude Code's bash gateway rejected it with Error: Contains command_substitution (the $(cat ...) form is forbidden).
  3. The agent improvised by reading a PID it had seen earlier and running kill -TERM 179. PID 179 was inside the agent's own awf container — killing it triggered immediate container teardown, which exited 143.

A previous attempt at this fix wrapped kill/wait with || true for SIGTERM, but that addressed the wrong layer: the agent's bash call already returned 0, and the 143 was coming from the awf wrapper exiting after its child process was killed. The new snippets also still used \$(cat server.pid), which would have been rejected the same way.

This PR replaces every server-stop primitive with pkill -f "next start", which:

  • requires no PID lookup,
  • uses no command substitution (\$(...)),
  • never targets a hardcoded PID,
  • is already on the bash allow-list (Bash(pkill:*)).

Changes are prompt-only (nighthawk.md); nighthawk.lock.yml shows no content diff because the prompt body is pulled in at job time via {{#runtime-import .github/workflows/nighthawk.md}}.

Edits in nighthawk.md

  • Step 7 path list: removed server.pid (no longer used).
  • Step 8 start snippet: removed echo \$! > server.pid; explicit "do not capture or store the PID".
  • Step 8 bash-gateway callout: rewrote with 6 numbered rules — \$(...) is banned, never hardcode a PID, never use kill -TERM <pid>, never use wait, use pkill -f exclusively.
  • Step 10 step 2 (mid-iteration stop): pkill -TERM -f "next start" 2>/dev/null || true + sleep 2.
  • Step 11 step 1 (final cleanup): pkill -TERM -f then sleep 2 then pkill -KILL -f, both with || true.
  • Important Notes: rewrote the durable rule with the actual incident (hardcoded PID killed agent's own container).

Test plan

  • Trigger nighthawk on a small open issue and confirm step 23 ("Execute Claude Code CLI") completes without exit 143.
  • Confirm the agent uses pkill -TERM -f "next start" (not kill -TERM <pid>) when stopping the server between iterations.
  • Confirm Step 11 cleanup runs the final pkill -TERM + pkill -KILL pair and the awf container shuts down cleanly afterward.
  • Confirm server.pid is never written.

🤖 Generated with Claude Code

The agent was killing its own awf container after Claude Code's bash
gateway rejected `kill -TERM $(cat server.pid)` for command substitution:
it improvised by hardcoding a PID seen earlier, which matched a process
inside the agent container and tore the run down with exit 143.

Replace every server-stop primitive in Steps 10 and 11 with
`pkill -TERM/-KILL -f "next start" 2>/dev/null || true`. No PID lookup,
no command substitution, no hardcoded PIDs. Strengthen the Step 8 bash-
gateway callout with explicit prohibitions and rewrite the durable rule
in Important Notes to document the actual outage.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 4, 2026 07:35
@vercel
Copy link
Copy Markdown

vercel Bot commented May 4, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
ai-developer-hub Ready Ready Preview, Comment May 4, 2026 8:04am

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the Nighthawk workflow prompt to stop the local Next.js sandbox server via pkill -f "next start" instead of PID-based kill, addressing workflow failures caused by the Bash gateway rejecting command substitution and preventing accidental self-termination of the AWF container.

Changes:

  • Remove PID capture/storage guidance (server.pid, $!) and replace stop/cleanup instructions with pkill -TERM/-KILL -f "next start" ... || true.
  • Expand the “Bash gateway constraints” section with explicit rules forbidding $(...), hardcoded PIDs, kill <pid>, and wait.
  • Update per-iteration and final cleanup steps to use the new server-stop primitive consistently.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 429 to 433
@@ -432,7 +433,20 @@ for i in $(seq 1 60); do
done
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 658b451. Switched the Wait for ready loop to for i in {1..60}; do …; done (brace expansion is parse-time, not command substitution) and added $(seq 1 60) to the explicit list of rejected forms in the bash-gateway callout so the agent doesn't reach for seq again.

… loop

Address Copilot PR review feedback on #79. The Step 8 "Wait for ready"
loop still used `for i in $(seq 1 60)` — same command-substitution
violation that caused the original outage. Switch to `for i in {1..60}`
(parse-time brace expansion, no $(...) involved) and add `seq` to the
explicit list of rejected forms in the bash-gateway callout.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@studert studert merged commit 5c52d46 into main May 4, 2026
7 checks passed
@studert
Copy link
Copy Markdown
Member Author

studert commented May 4, 2026

This closes #77

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants