Fix Copilot engine startup in AWF by expanding Node toolcache PATH discovery#31224
Conversation
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
|
📰 BREAKING: Smoke Copilot is now investigating this pull request. Sources say the story is developing... |
|
💫 TO BE CONTINUED... Smoke Claude failed to deliver outputs! Our hero faces unexpected challenges... |
|
|
|
🚀 Smoke Pi MISSION COMPLETE! Pi delivered. 🥧 |
There was a problem hiding this comment.
Pull request overview
This PR aims to prevent Copilot engine startup failures in AWF/chroot environments by expanding Node.js toolcache PATH discovery so node can be resolved reliably across runner layouts.
Changes:
- Updated
GetNpmBinPathSetup()to search one directory level deeper (find ... -maxdepth 5). - Updated/extended unit tests to assert the new
-maxdepth 5behavior. - Updated many workflow lockfiles to propagate setup tracing identifiers (
setup-span-id/setup-parent-span-id) across jobs.
Show a summary per file
| File | Description |
|---|---|
| pkg/workflow/nodejs.go | Expand hostedtoolcache bin discovery to -maxdepth 5 in PATH setup. |
| pkg/workflow/engine_helpers_test.go | Update/add assertions covering the new -maxdepth 5 PATH setup behavior. |
| .github/workflows/workflow-skill-extractor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/workflow-normalizer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/workflow-health-manager.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/weekly-safe-outputs-spec-review.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/weekly-editors-health-check.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/weekly-blog-post-writer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/video-analyzer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/typist.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/test-workflow.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/test-project-url-default.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/test-dispatcher.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/test-create-pr-error-handling.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/terminal-stylist.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/super-linter.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/sub-issue-closer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/step-name-alignment.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/static-analysis-report.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/stale-pr-cleanup.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/spec-extractor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/spec-enforcer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/sergo.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/semantic-function-refactor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/security-compliance.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/schema-consistency-checker.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/safe-output-health.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/research.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/repo-tree-map.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/release.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps (including pre-activation). |
| .github/workflows/notion-issue-summary.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/metrics-collector.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/mcp-inspector.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/lockfile-stats.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/layout-spec-maintainer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/jsweep.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/issue-triage-agent.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/instructions-janitor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/hourly-ci-cleaner.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/hippo-embed.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/gpclean.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/go-pattern-detector.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/go-logger.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/go-fan.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/github-remote-mcp-auth-test.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/github-mcp-tools-report.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/functional-pragmatist.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/firewall.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/example-workflow-analyzer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/example-permissions-warning.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/draft-pr-cleanup.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/docs-noob-tester.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/dictation-prompt.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/dependabot-go-checker.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/dependabot-burner.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/delight.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-workflow-updater.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-token-consumption-report.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-team-evolution-insights.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-syntax-error-quality.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-subagent-optimizer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-skill-optimizer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-semgrep-scan.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-security-red-team.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-secrets-analysis.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-safe-outputs-conformance.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-safe-output-integrator.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-regulatory.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-otel-instrumentation-advisor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-multi-device-docs-tester.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-model-inventory.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-malicious-code-scan.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-grafana-otel-instrumentation-advisor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-geo-optimizer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-function-namer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-doc-updater.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-doc-healer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-compiler-threat-spec-optimizer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-compiler-quality.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-cli-tools-tester.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-choice-test.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-assign-issue-to-user.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/daily-architecture-diagram.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/copilot-token-optimizer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/copilot-opt.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/contribution-check.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/commit-changes-analyzer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/codex-github-remote-mcp-test.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/cli-version-checker.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/cli-consistency-checker.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/ci-coach.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/changeset.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps (including pre-activation). |
| .github/workflows/bot-detection.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/blog-auditor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/aw-failure-investigator.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/artifacts-summary.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/agent-persona-explorer.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
| .github/workflows/ace-editor.lock.yml | Add setup span outputs and pass parent-span-id to downstream setup steps. |
Copilot's findings
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 224/224 changed files
- Comments generated: 2
| model: ${{ steps.generate_aw_info.outputs.model }} | ||
| secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} | ||
| setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} | ||
| setup-span-id: ${{ steps.setup.outputs.span-id }} | ||
| setup-trace-id: ${{ steps.setup.outputs.trace-id }} |
| secret_verification_result: ${{ steps.validate-secret.outputs.verification_result }} | ||
| setup-parent-span-id: ${{ steps.setup.outputs.parent-span-id || steps.setup.outputs.span-id }} | ||
| setup-span-id: ${{ steps.setup.outputs.span-id }} | ||
| setup-trace-id: ${{ steps.setup.outputs.trace-id }} |
Agent Container Tool Check
Result: 12/12 tools available ✅ Overall Status: PASS
|
There was a problem hiding this comment.
Skills-Based Review 🧠
Applied /diagnose and /tdd — this is a bug fix with targeted test and golden-file updates.
Key Themes
-
Magic number opacity:
maxdepth 5is correct but has no inline documentation tying it to a real toolcache path depth. Without this, the next time the depth changes (runner image update, new toolcache layout), reviewers have no fast way to validate the new value. -
Implementation-detail tests: The new assertion checks for the string
-maxdepth 5rather than exercising the observable behaviour (does the PATH snippet actually resolve a binary at the depth expected fromsetup-node?). A behavioural test usingt.TempDir()to create a synthetic toolcache would have caught the depth-4 bug automatically.
Positive Highlights
- ✅ Root cause is correctly identified and the one-line fix is minimal and surgical.
- ✅ All three relevant test scenarios (
TestGetNpmBinPathSetup,GorootOrdering,NoGorootDoesNotBreakChain) were updated consistently. - ✅ Golden files refreshed correctly — no partial updates left behind.
- ✅ PR description includes a clear before/after example.
Verdict
Comments only — the fix itself is sound and the tests are updated. The inline suggestions around documentation and test quality are worth considering to prevent the same class of regression repeating silently.
🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer · ● 5M
| // ensures the Go version set by actions/setup-go takes precedence. | ||
| // AWF's entrypoint.sh exports GOROOT before the user command runs. | ||
| return `export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 4 -type d -name bin 2>/dev/null | tr '\n' ':')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true` | ||
| return `export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 -type d -name bin 2>/dev/null | tr '\n' ':')$PATH"; [ -n "$GOROOT" ] && export PATH="$GOROOT/bin:$PATH" || true` |
There was a problem hiding this comment.
[/diagnose] The magic number 5 is just as opaque as the 4 it replaces. The comment above explains why find is used, but not what specific toolcache path depth triggers this value.
Without documenting the actual failing path structure, the next regression will require another round of binary-search depth bumping. Consider adding a brief comment anchoring 5 to the concrete runner layout it covers:
// /home/runner/work/_tool/node/<version>/<arch>/bin reaches depth 5
// (root → node → version → arch → bin = 5 levels)
return `export PATH="$(find /opt/hostedtoolcache /home/runner/work/_tool -maxdepth 5 ...`| if !strings.Contains(pathSetup, "-name bin") { | ||
| t.Errorf("PATH setup should search for bin directories, got: %s", pathSetup) | ||
| } | ||
| if !strings.Contains(pathSetup, "-maxdepth 5") { |
There was a problem hiding this comment.
[/tdd] This assertion tests an implementation detail (the literal string -maxdepth 5) rather than the observable behaviour ("the PATH setup actually locates node binaries at the depth used by setup-node").
A behavioural test would create a temporary directory mimicking the toolcache layout (/tmp/tc/node/22.0.0/x64/bin/node) and verify that evaluating the generated PATH snippet makes node reachable:
// Arrange: fake toolcache at depth 5
toolcache := t.TempDir()
binDir := filepath.Join(toolcache, "node", "22.0.0", "x64", "bin")
os.MkdirAll(binDir, 0755)
os.WriteFile(filepath.Join(binDir, "node"), []byte("#!/bin/sh\necho ok"), 0755)
// Act
setup := GetNpmBinPathSetup() // or a variant accepting root paths
shellCmd := fmt.Sprintf(`%s && node`, strings.ReplaceAll(setup, "/opt/hostedtoolcache /home/runner/work/_tool", toolcache))
out, err := exec.Command("bash", "-c", shellCmd).Output()
// Assert
require.NoError(t, err)
assert.Equal(t, "ok\n", string(out))This would have caught the depth-4 bug automatically rather than relying on the production failure.
|
test
|
|
Commit pushed:
|
💥 Smoke Test: Claude — Run 25605079533Core (1-12): ✅ all 12 Status: PASS · §25605079533 Warning Firewall blocked 6 domainsThe following domains were blocked by the firewall during workflow execution:
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.
|
There was a problem hiding this comment.
💥 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.comandroid.clients.google.comclients2.google.comcontentautofill.googleapis.comsafebrowsingohttpgateway.googleapis.comwww.google.com
To allow these domains, add them to the
network.allowedlist 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 · ● 3.8M
|
Ooga booga! Me smoke test agent! Me was here! Me test things. Things work good! 🦴 Warning Firewall blocked 6 domainsThe following domains were blocked by the firewall during workflow execution:
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.
|
|
🦴 UNGA BUNGA! Me caveman smoke test! Me come here, me test all things! Discussion born! Test pass! Much wow! 🎉 Smoke test #25605079522 complete. Caveman satisfied! Warning Firewall blocked 6 domainsThe following domains were blocked by the firewall during workflow execution:
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.
|
There was a problem hiding this comment.
Caveman review PR! maxdepth 4 change to 5 look good. Node find now! Test golden files update correct. Me approve change.
Warning
Firewall blocked 6 domains
The following domains were blocked by the firewall during workflow execution:
accounts.google.comandroid.clients.google.comclients2.google.comcontentautofill.googleapis.comsafebrowsingohttpgateway.googleapis.comwww.google.com
To allow these domains, add them to the
network.allowedlist 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 · ● 11.3M
|
📰 VERDICT: Smoke Copilot has concluded. All systems operational. This is a developing story. 🎤 |
Bug Fix
What was the bug?
Daily Issues Report Generatorfailed because the Copilot engine exited before producing output. In the failing run, the AWF sandbox could not resolvenode, causing the Copilot process to terminate with exit code 127.How did you fix it?
Copilot runtime PATH resolution
GetNpmBinPathSetup()to search deeper toolcache paths by changing:find ... -maxdepth 4 ...find ... -maxdepth 5 ...nodeis nested one level deeper.Targeted helper/test updates
engine_helpers_test.goto match-maxdepth 5.-maxdepth 5.Golden fixture refresh
Example
Changeset
✨ PR Review Safe Output Test - Run 25605079533
Warning
Firewall blocked 6 domains
The following domains were blocked by the firewall during workflow execution:
accounts.google.comandroid.clients.google.comclients2.google.comcontentautofill.googleapis.comsafebrowsingohttpgateway.googleapis.comwww.google.comSee Network Configuration for more information.