Skip to content

fix: reclaim stale root-owned /tmp/gh-aw before AWF invocation#44022

Merged
lpcox merged 3 commits into
mainfrom
fix/reclaim-stale-sandbox-dir-before-awf
Jul 7, 2026
Merged

fix: reclaim stale root-owned /tmp/gh-aw before AWF invocation#44022
lpcox merged 3 commits into
mainfrom
fix/reclaim-stale-sandbox-dir-before-awf

Conversation

@lpcox

@lpcox lpcox commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes two related bugs where stale root-owned files from a previous AWF run break subsequent invocations on persistent GitHub-hosted runners.

Changes

actions/setup/setup.sh — robust /tmp/gh-aw reclamation

Replaces the unconditional rm -rf /tmp/gh-aw with a two-branch conditional that handles root-owned directories:

  • Root-owned top-level dir (! -w /tmp/gh-aw): escalates immediately to sudo -n rm -rf.
  • Writable top-level with root-owned subdirectories (e.g., sandbox/firewall/): attempts plain rm -rf; falls back to sudo -n rm -rf on EACCES.
  • If sudo is unavailable in either branch, emits a ::error:: annotation and exits with code 1.

Root cause: on persistent runners, a prior AWF run leaves /tmp/gh-aw or its subdirectories owned by root. The plain rm -rf fails silently or exits non-zero, preventing a clean workspace for the next run.

pkg/workflow/engine_firewall_support.go — best-effort chmod in network isolation mode

Adds an else branch to generateFirewallLogParsingStep for the isAWFNetworkIsolationEnabled path. Previously, the sudo-chmod step was entirely absent in rootless mode. Now the generated step includes:

sudo -n chmod -R a+rX <firewallDir> 2>/dev/null || chmod -R a+rX <firewallDir> 2>/dev/null || true

Root cause: Docker containers running inside AWF write files under non-runner UIDs even in rootless mode (e.g., Squid writes as UID 13). AWF's post-run cleanup (fixArtifactPermissionsForRootless) normally corrects this, but is skipped on timeout or OOM kill, leaving firewall logs unreadable for artifact upload. The sudo -n || chmod || true pattern is non-fatal and best-effort.

pkg/workflow/engine_firewall_support_test.go — test coverage

Updates TestGenerateFirewallLogParsingStepNetworkIsolationOmitsSudo:

  • Retains the existing assertion that sudo chmod is absent (updated error message).
  • Adds a positive assertion that chmod -R a+rX is present, validating the new best-effort fallback.

Motivation

Both issues manifest only on persistent/reused runners where prior AWF runs leave behind root-owned state. The fixes are defensive: they tolerate common runner configurations and degrade gracefully when sudo is unavailable.

Testing

  • Existing unit test updated and passing.
  • Shell logic follows standard POSIX conditional patterns; sudo -n ensures non-interactive, non-password-prompting escalation.
Commits
  • 5a2138b8d fix: reclaim stale root-owned /tmp/gh-aw before AWF invocation
  • a0ef41764 Potential fix for pull request finding
  • 470a2bdfc Potential fix for pull request finding

Generated by PR Description Updater for #44022 · 38.1 AIC · ⌖ 9.24 AIC · ⊞ 4.7K ·

On persistent runners, a previous AWF run can leave /tmp/gh-aw/sandbox/
owned by root. The next run's setup.sh does `rm -rf /tmp/gh-aw` which
silently fails (EACCES), then AWF's mkdirSync fails with:

  EACCES: permission denied, mkdir '/tmp/gh-aw/sandbox/firewall/logs'

## Changes

### actions/setup/setup.sh
- Check if /tmp/gh-aw is writable before attempting removal
- Fall back to `sudo rm -rf` when the directory (or its children) are
  not writable by the current user
- Works on GitHub-hosted runners where sudo is passwordless

### pkg/workflow/engine_firewall_support.go
- Add best-effort `chmod -R a+rX` in network-isolation mode (non-sudo)
- Previously, the post-run chmod was skipped entirely when network-isolation
  was enabled, assuming rootless == no root-owned files. This is incorrect:
  Docker containers still write as non-runner UIDs (Squid: UID 13), and if
  AWF is killed by timeout/OOM, its cleanup never runs.

### pkg/workflow/engine_firewall_support_test.go
- Update test assertions to expect non-sudo chmod in network-isolation mode

Ref: https://github.com/github/gh-aw/actions/runs/28856007222/job/85583002595
Supersedes: #42400

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 7, 2026 12:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This pull request addresses intermittent EACCES failures on persistent runners caused by stale, root-owned (or otherwise non-writable) state under /tmp/gh-aw left behind by prior AWF runs, ensuring the next AWF invocation can create its sandbox directories reliably.

Changes:

  • Harden actions/setup/setup.sh to reclaim /tmp/gh-aw using a sudo fallback when plain rm -rf cannot remove root-owned/non-writable trees.
  • Update firewall log parsing step generation to run a best-effort permission fix even when AWF network isolation is enabled.
  • Adjust tests to reflect the updated network-isolation chmod behavior.
Show a summary per file
File Description
actions/setup/setup.sh Adds pre-flight cleanup logic to remove /tmp/gh-aw even when prior runs left non-writable/root-owned contents.
pkg/workflow/engine_firewall_support.go Emits a chmod-based post-run permission “safety net” for firewall artifacts in network-isolation mode.
pkg/workflow/engine_firewall_support_test.go Updates assertions for the network-isolation firewall log parsing step behavior.

Review details

Tip

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

  • Files reviewed: 3/3 changed files
  • Comments generated: 2
  • Review effort level: Low

Comment thread pkg/workflow/engine_firewall_support.go
Comment thread actions/setup/setup.sh
lpcox and others added 2 commits July 7, 2026 06:07
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@lpcox lpcox added the smoke label Jul 7, 2026
@lpcox

lpcox commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator Author

@copilot run pr-finisher skill

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Smoke Antigravity MISSION COMPLETE! Antigravity has spoken. ✨

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

✅ All tools validated successfully! Agent Container Smoke Test confirms agent container is ready.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Smoke Gemini MISSION COMPLETE! Gemini has spoken. ✨

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🎬 THE ENDSmoke Claude MISSION: ACCOMPLISHED! The hero saves the day! ✨

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

✨ The prophecy is fulfilled... Smoke Codex has completed its mystical journey. The stars align. 🌟

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧

Smoke test completed; issue created and PR comment added. Label not added because not all tests passed.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing...

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot - AOAI (Entra) is now investigating this pull request. Sources say the story is developing...

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

📰 BREAKING: Smoke Copilot - AOAI (apikey) is now investigating this pull request. Sources say the story is developing...

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Smoke test

  • GitHub CLI ✅
  • Web fetch ❌
  • File write ✅
  • Bash verify ✅
  • Build ❌
  • Overall: FAIL

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • proxy.golang.org

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "proxy.golang.org"

See Network Configuration for more information.

🥧 Smoke Pi — Powered by Pi · 1.35 AIC · ⌖ 3.73 AIC · ⊞ 4.4K ·
Comment /smoke-pi to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Gemini Results

  • GitHub MCP: ✅
  • Web Fetch: ✅
  • File Writing: ✅
  • Bash: ✅
  • Build: ❌

Overall Status: FAIL

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • localhost

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "localhost"

See Network Configuration for more information.

Smoke Gemini — Powered by Gemini ·
Comment /smoke-gemini to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Agent Container Tool Check

Tool Status Version
bash 5.2.21
sh available
git 2.54.0
jq 1.7
yq v4.53.3
curl 8.5.0
gh 2.95.0
node v22.23.1
python3 3.11.15 (PyPy 7.3.23)
go 1.24.13
java 21.0.11
dotnet 10.0.301

Result: 12/12 tools available ✅

Overall Status: PASS

Warning

Firewall blocked 1 domain

The following domain was blocked by the firewall during workflow execution:

  • awmgmcpg

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "awmgmcpg"

See Network Configuration for more information.

🔧 Tool validation by Agent Container Smoke Test · 13.3 AIC · ⌖ 5.91 AIC · ⊞ 4.6K ·
Comment /smoke-test-tools to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Smoke Test: Codex - 28868608114\n#43967 fix: suppress osgetenvlibrary lint findings in pkg/cli and pkg/workflow\n#43957 Recreate AWF firewall v0.27.26 integration and artifact refresh\n✅/❌ results recorded in issue #44026\nOverall status: FAIL

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex · 9.1 AIC · ⌖ 5.14 AIC · ⊞ 10.8K ·
Comment /smoke-codex to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Comment Memory

Quiet cache dawn
Build lights in the corridor
Smoke test keeps its word

Note

This comment is managed by comment memory.

It stores persistent context for this thread in the code block at the top of this comment.
Edit only the text inside the backtick fences; workflow metadata and the footer are regenerated automatically.

Learn more about comment memory

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

🔮 The oracle has spoken through Smoke Codex · 9.1 AIC · ⌖ 5.14 AIC · ⊞ 10.8K ·
Comment /smoke-codex to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

💥 Smoke Test: Claude — Run 28868607863

Core #1-12: all ✅
PR Review: 13✅ 14✅ 15✅ 16⚠️ 17✅ 18⚠️ 19⚠️

Overall: PARTIAL (16: no unresolved threads; 18: allowed-files config; 19: no safe test PR)

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · 72.4 AIC · ⌖ 14.7 AIC · ⊞ 8.4K ·
Comment /smoke-claude to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💥 Automated smoke test review - all systems nominal!

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

💥 [THE END] — Illustrated by Smoke Claude · 72.4 AIC · ⌖ 14.7 AIC · ⊞ 8.4K
Comment /smoke-claude to run again

Comment thread actions/setup/setup.sh
if [ -d /tmp/gh-aw ] && [ ! -w /tmp/gh-aw ]; then
debug_log "/tmp/gh-aw exists but is not writable (likely root-owned from prior run); using sudo to remove"
if command -v sudo >/dev/null 2>&1; then
sudo -n rm -rf /tmp/gh-aw

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The passwordless sudo -n rm -rf fallback is a solid approach for GitHub-hosted runners. Consider logging when the sudo path is taken to aid future debugging.


// When sudo is false (network isolation mode), AWF runs rootless so firewall files
// are not owned by root — skip the sudo chmod permission-fix step.
// When sudo is false (network isolation mode), AWF runs rootless but Docker

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good clarification in this comment — noting that Docker containers write as non-runner UIDs (e.g. Squid UID 13) makes the rationale much clearer.

Copilot AI commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@copilot run pr-finisher skill

Ran a pr-finisher pass.

  • Prior CI failure 28856007222 was inspected at job-log level (85583002595) and confirms the original EACCES: permission denied, lstat '/tmp/gh-aw/sandbox/firewall/logs' root cause this PR addresses.
  • Current branch has no additional in-scope @copilot action items requiring code changes.
  • Targeted local validation for this change area passes:
    • go test ./pkg/workflow -run 'TestGenerateFirewallLogParsingStep'
    • bash -n actions/setup/setup.sh

CI on the current head remains unverified until a maintainer re-triggers workflows (close/reopen PR, workflow_dispatch, or maintainer push).

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Caveman smoke pass. Left two tiny notes.

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot · 73.8 AIC · ⌖ 3.43 AIC · ⊞ 19K
Comment /smoke-copilot to run again
Add label smoke to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Smoke Test Results:

  1. List merged PRs: ✅
  2. mcpscripts-gh list: ✅
  3. Serena find_symbol: ❌
  4. Playwright CLI: ✅
  5. curl fetch: ✅
  6. File create: ✅
  7. Discussion interaction: ❌
  8. Build: ❌

Overall: FAIL

@lpcox

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot - AOAI (apikey) · 44.3 AIC · ⌖ 3.01 AIC · ⊞ 17.8K ·
Comment /smoke-copilot-aoai-apikey to run again
Add label smoke to run again

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning

Firewall blocked 6 domains

The following domains were blocked by the firewall during workflow execution:

  • accounts.google.com
  • android.clients.google.com
  • clients2.google.com
  • contentautofill.googleapis.com
  • safebrowsingohttpgateway.googleapis.com
  • www.google.com

To allow these domains, add them to the network.allowed list in your workflow frontmatter:

network:
  allowed:
    - defaults
    - "accounts.google.com"
    - "android.clients.google.com"
    - "clients2.google.com"
    - "contentautofill.googleapis.com"
    - "safebrowsingohttpgateway.googleapis.com"
    - "www.google.com"

See Network Configuration for more information.

📰 BREAKING: Report filed by Smoke Copilot - AOAI (apikey) · 44.3 AIC · ⌖ 3.01 AIC · ⊞ 17.8K
Comment /smoke-copilot-aoai-apikey to run again
Add label smoke to run again

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Hey @lpcox 👋 — thanks for working on this fix for the stale root-owned /tmp/gh-aw issue! The diagnosis is solid and the approach is clean. However, there's a process issue that needs to be addressed first.

  • Contribution process — according to CONTRIBUTING.md, non-core team members should not open PRs directly. Instead, the preferred path is to create a detailed agentic plan in an issue, discuss it with the team, and a core team member will implement it using agents. This keeps the codebase consistent with the project's agentic development model.

If you'd like to get this fix in, the recommended next step is to open an issue describing the problem and your proposed solution (you can reuse most of this PR's body — it's already very well written!). The core team can then pick it up and implement it through the standard workflow.

If you'd like a hand drafting that issue, you can assign this prompt to your coding agent:

Create a GitHub issue in github/gh-aw describing the following bug and fix:

Bug: On persistent runners, a previous AWF run can leave /tmp/gh-aw/sandbox/firewall/ owned by root. The setup action's `rm -rf /tmp/gh-aw` fails silently (EACCES), and AWF's mkdirSync then fails with EACCES.

Proposed fix:
1. In actions/setup/setup.sh, add a pre-flight reclaim block that detects non-writable /tmp/gh-aw and falls back to `sudo rm -rf /tmp/gh-aw`.
2. In pkg/workflow/engine_firewall_support.go, emit a non-sudo `chmod -R a+rX` as a best-effort fallback even in network-isolation mode.

Format the issue as an agentic plan following the project's contributing guidelines.

Generated by ✅ Contribution Check · 134.6 AIC · ⌖ 17.7 AIC · ⊞ 6.2K ·

@lpcox lpcox merged commit 70040a5 into main Jul 7, 2026
223 of 228 checks passed
@lpcox lpcox deleted the fix/reclaim-stale-sandbox-dir-before-awf branch July 7, 2026 13:48
@github-actions

github-actions Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

🎉 This pull request is included in a new release.

Release: v0.82.4

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants