Skip to content

fix: handle SIGPIPE in Fetch PR changed files step to prevent missing delimiter error#1651

Merged
lpcox merged 1 commit intoperf/security-guard-token-optimizationfrom
copilot/fix-github-actions-workflow-agent-again
Apr 3, 2026
Merged

fix: handle SIGPIPE in Fetch PR changed files step to prevent missing delimiter error#1651
lpcox merged 1 commit intoperf/security-guard-token-optimizationfrom
copilot/fix-github-actions-workflow-agent-again

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 3, 2026

Root Cause

When the Security Guard workflow ran on PR #1648 (perf/security-guard-token-optimization), the "Fetch PR changed files" step failed with:

##[error]Unable to process file command 'output' successfully.
##[error]Invalid value. Matching delimiter not found 'GHAW_PR_FILES_1775255800'

Why it failed: GitHub Actions' default bash shell runs with -eo pipefail. When gh api ... | head -c 8000 executes and the PR diff exceeds 8000 bytes:

  1. head -c 8000 reads exactly 8000 bytes and exits cleanly (exit 0)
  2. gh api receives SIGPIPE (exit code 141) when it tries to write more data
  3. With pipefail, the pipeline's exit code is 141 (non-zero)
  4. With errexit, the subshell aborts before writing the closing delimiter echo "${DELIM}"
  5. GITHUB_OUTPUT has the opening PR_FILES<<GHAW_PR_FILES_... but no closing delimiter → error

Fix

Added || true after head -c 8000 to swallow the SIGPIPE/pipefail error, ensuring the subshell always reaches echo "${DELIM}":

gh api ... | head -c 8000 || true
echo "${DELIM}"

Changes

  • .github/workflows/security-guard.md — source workflow file
  • .github/workflows/security-guard.lock.yml — compiled workflow file

Fixes failing job: https://github.com/github/gh-aw-firewall/actions/runs/23964770751/job/69902358339

… delimiter error

When the PR diff exceeds 8000 bytes, `gh api ... | head -c 8000` causes
SIGPIPE (exit 141) on the gh api process. GitHub Actions bash uses
`-eo pipefail`, so the pipeline failure aborts the subshell before
writing the closing heredoc delimiter to GITHUB_OUTPUT, resulting in:

  ##[error]Invalid value. Matching delimiter not found 'GHAW_PR_FILES_...'

Fix: add `|| true` after `head -c 8000` to swallow the SIGPIPE/pipefail
error, ensuring the closing delimiter is always written to GITHUB_OUTPUT.

Fixes failing job: https://github.com/github/gh-aw-firewall/actions/runs/23964770751/job/69902358339

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/c8b8f958-f52e-4390-af7d-f094e20e68da

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI requested a review from lpcox April 3, 2026 22:44
Copilot finished work on behalf of lpcox April 3, 2026 22:44
@lpcox lpcox marked this pull request as ready for review April 3, 2026 22:55
@lpcox lpcox requested a review from Mossaka as a code owner April 3, 2026 22:55
Copilot AI review requested due to automatic review settings April 3, 2026 22:55
@lpcox lpcox merged commit 6d1b944 into perf/security-guard-token-optimization Apr 3, 2026
@lpcox lpcox deleted the copilot/fix-github-actions-workflow-agent-again branch April 3, 2026 22:55
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 Security Guard workflow’s “Fetch PR changed files” step to avoid a GitHub Actions GITHUB_OUTPUT delimiter error caused by bash -eo pipefail aborting on SIGPIPE when truncating large PR diffs.

Changes:

  • Swallow the pipeline failure from gh api ... | head -c 8000 by appending || true so the closing delimiter is always written.
  • Apply the same change to both the source workflow (.md) and the compiled workflow (.lock.yml).
Show a summary per file
File Description
.github/workflows/security-guard.md Adds `
.github/workflows/security-guard.lock.yml Mirrors the same `

Copilot's findings

Tip

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

  • Files reviewed: 2/2 changed files
  • Comments generated: 2

Comment on lines 33 to 36
gh api "repos/${GH_REPO}/pulls/${PR_NUMBER}/files" \
--paginate --jq '.[] | "### " + .filename + " (+" + (.additions|tostring) + "/-" + (.deletions|tostring) + ")\n" + (.patch // "") + "\n"' \
| head -c 8000
| head -c 8000 || true
echo "${DELIM}"
Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

| head -c 8000 || true prevents the delimiter-missing failure, but it also suppresses all non-zero exits from the pipeline (e.g., gh api auth/permission/rate-limit failures), which can cause the workflow to proceed with an empty/incomplete PR_FILES output and silently degrade the security review.

Consider handling only the expected SIGPIPE/pipefail case (exit 141) while still closing the delimiter, and re-failing the step for any other error (e.g., by temporarily disabling errexit around the pipeline, capturing the pipeline/PIPESTATUS exit code, then deciding whether to ignore or exit).

See below for a potential fix:

      pipeline_status=0
      pipe_status=()
      {
        echo "PR_FILES<<${DELIM}"
        set +e
        gh api "repos/${GH_REPO}/pulls/${PR_NUMBER}/files" \
          --paginate --jq '.[] | "### " + .filename + " (+" + (.additions|tostring) + "/-" + (.deletions|tostring) + ")\n" + (.patch // "") + "\n"' \
          | head -c 8000
        pipeline_status=$?
        pipe_status=("${PIPESTATUS[@]}")
        set -e
        echo "${DELIM}"
      } >> "$GITHUB_OUTPUT"
      if [ "$pipeline_status" -ne 0 ]; then
        if [ "${#pipe_status[@]}" -eq 2 ] && [ "${pipe_status[0]}" -eq 141 ] && [ "${pipe_status[1]}" -eq 0 ]; then
          :
        else
          exit "$pipeline_status"
        fi
      fi

Copilot uses AI. Check for mistakes.
Comment on lines +316 to 317
run: "DELIM=\"GHAW_PR_FILES_$(date +%s)\"\n{\n echo \"PR_FILES<<${DELIM}\"\n gh api \"repos/${GH_REPO}/pulls/${PR_NUMBER}/files\" \\\n --paginate --jq '.[] | \"### \" + .filename + \" (+\" + (.additions|tostring) + \"/-\" + (.deletions|tostring) + \")\\n\" + (.patch // \"\") + \"\\n\"' \\\n | head -c 8000 || true\n echo \"${DELIM}\"\n} >> \"$GITHUB_OUTPUT\"\n"

Copy link

Copilot AI Apr 3, 2026

Choose a reason for hiding this comment

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

The added || true fixes the missing-delimiter error, but it also masks genuine gh api failures (auth/permission/rate-limit/network), letting the job continue with an empty/truncated PR_FILES output.

Recommend adjusting the script to ignore only the expected SIGPIPE/pipefail exit (141) while still emitting the closing delimiter, and to fail the step for other non-zero statuses.

Suggested change
run: "DELIM=\"GHAW_PR_FILES_$(date +%s)\"\n{\n echo \"PR_FILES<<${DELIM}\"\n gh api \"repos/${GH_REPO}/pulls/${PR_NUMBER}/files\" \\\n --paginate --jq '.[] | \"### \" + .filename + \" (+\" + (.additions|tostring) + \"/-\" + (.deletions|tostring) + \")\\n\" + (.patch // \"\") + \"\\n\"' \\\n | head -c 8000 || true\n echo \"${DELIM}\"\n} >> \"$GITHUB_OUTPUT\"\n"
run: |
DELIM="GHAW_PR_FILES_$(date +%s)"
{
echo "PR_FILES<<${DELIM}"
set +e
gh api "repos/${GH_REPO}/pulls/${PR_NUMBER}/files" \
--paginate --jq '.[] | "### " + .filename + " (+" + (.additions|tostring) + "/-" + (.deletions|tostring) + ")\n" + (.patch // "") + "\n"' \
| head -c 8000
status=$?
set -e
echo "${DELIM}"
} >> "$GITHUB_OUTPUT"
if [ "$status" -ne 0 ] && [ "$status" -ne 141 ]; then
exit "$status"
fi

Copilot uses AI. Check for mistakes.
lpcox added a commit that referenced this pull request Apr 3, 2026
* perf: optimize security-guard token usage

- Restrict GitHub toolsets from [default] (52 tools) to
  [pull_requests, repos] (only tools actually used)
- Add pre-compute step to fetch PR diff before agent starts,
  reducing tool calls needed for initial PR analysis
- Add max-turns: 15 to prevent runaway token consumption
- Add explicit network: allowed: [github] to restrict egress
- Update prompt to reference pre-fetched diff data

Closes #1647

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: address review feedback on pre-compute step

- Fix GITHUB_OUTPUT redirect: wrap gh api + delimiters in block
  redirect so output actually reaches the step output variable
- Add if: guard for workflow_dispatch where PR number is absent
- Network groups: kept as github-only since compiler auto-adds
  Claude API domains; api-proxy is not a standard network group

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: use jq string concatenation to avoid YAML escaping issue

The jq string interpolation with escaped quotes (\"") gets
double-escaped by the gh-aw compiler's YAML quoting, producing
invalid jq at runtime. Switch to string concatenation (+) which
avoids nested quotes entirely.

Also simplifies the binary fallback from '"(binary)"' to '""'
since binary files with no patch data aren't useful for review.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: use unique heredoc delimiter to avoid EOF collision

The PR diff content can contain literal 'EOF' strings (e.g., from
heredoc usage in shell scripts), which prematurely closes the
GITHUB_OUTPUT delimiter. Use a timestamp-based unique delimiter
(GHAW_PR_FILES_<epoch>) that won't collide with diff content.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: handle SIGPIPE in Fetch PR changed files step to prevent missing delimiter error (#1651)

When the PR diff exceeds 8000 bytes, `gh api ... | head -c 8000` causes
SIGPIPE (exit 141) on the gh api process. GitHub Actions bash uses
`-eo pipefail`, so the pipeline failure aborts the subshell before
writing the closing heredoc delimiter to GITHUB_OUTPUT, resulting in:

  ##[error]Invalid value. Matching delimiter not found 'GHAW_PR_FILES_...'

Fix: add `|| true` after `head -c 8000` to swallow the SIGPIPE/pipefail
error, ensuring the closing delimiter is always written to GITHUB_OUTPUT.

Fixes failing job: https://github.com/github/gh-aw-firewall/actions/runs/23964770751/job/69902358339

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/c8b8f958-f52e-4390-af7d-f094e20e68da

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: recompile security-guard.lock.yml to fix frontmatter hash mismatch (#1652)

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/0e4673e6-6f23-4e2d-8cc7-ccb922b81091

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

* fix: ensure newline before heredoc closing delimiter

head -c 8000 can truncate mid-line, leaving no trailing newline.
The closing delimiter then appears on the same line as content
and GitHub Actions fails to recognize it. Add an explicit echo
to guarantee the delimiter is on its own line.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: increase smoke-claude max-turns and fix playwright log dir permissions (#1653)

Root cause: Claude exceeded max-turns (9 > 8) because mcp__playwright__browser_navigate
failed 3 times with EACCES on /tmp/gh-aw/mcp-logs/playwright/*.yml, consuming extra turns.

Fixes:
1. Add pre-step to create /tmp/gh-aw/mcp-logs/playwright with chmod 777 before MCP
   Gateway starts - this ensures the playwright container can write page snapshot YAML files
2. Increase max-turns from 8 to 12 to handle transient playwright retries more robustly

Recompile smoke-claude.lock.yml and run post-processing scripts.

Agent-Logs-Url: https://github.com/github/gh-aw-firewall/sessions/7c6a8e3c-9a33-488d-a2a7-d54bdaed44a2

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
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.

3 participants