Post buffered inline comments fails on runners with /usr/bin/bun shim when allowed_non_write_users is set (original) (raw)

Summary

When allowed_non_write_users != "" is set and the action runs on a self-hosted runner image that installs supply-chain interception shims for package managers under /usr/bin/ (e.g. any runner with safe-chain enabled, which installs a pkg-bundled Node wrapper at /usr/bin/bun), the action's Post buffered inline comments post-step fails reliably with:

Error: Cannot find module '/home/runner/work/<repo>/<repo>/bun'
    at Module._resolveFilename (node:internal/modules/cjs/loader:1207:15)
    at Function._resolveFilename (pkg/prelude/bootstrap.js:1950:46)
    at Function.runMain (pkg/prelude/bootstrap.js:1978:12)
##[error]Process completed with exit code 1.

The main action step (Run Claude Code Action) completes successfully — review comments are posted via the action's normal flow. Only the post-step cleanup fails.

Root cause (verified against action.yml at v1.0.133)

allowed_non_write_users != "" triggers two composite sub-steps:

  1. Pin bun binary for post-stepscp <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mo stretchy="false">(</mo><mi>c</mi><mi>o</mi><mi>m</mi><mi>m</mi><mi>a</mi><mi>n</mi><mi>d</mi><mo>−</mo><mi>v</mi><mi>b</mi><mi>u</mi><mi>n</mi><mo stretchy="false">)</mo></mrow><annotation encoding="application/x-tex">(command -v bun) </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mopen">(</span><span class="mord mathnormal">co</span><span class="mord mathnormal">mman</span><span class="mord mathnormal">d</span><span class="mspace" style="margin-right:0.2222em;"></span><span class="mbin">−</span><span class="mspace" style="margin-right:0.2222em;"></span></span><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord mathnormal" style="margin-right:0.03588em;">v</span><span class="mord mathnormal">b</span><span class="mord mathnormal">u</span><span class="mord mathnormal">n</span><span class="mclose">)</span></span></span></span>GITHUB_ACTION_PATH/bin/bun. continue-on-error: true.
  2. Prepend system bin dirs to PATHecho "/usr/bin" >> "$GITHUB_PATH"; echo "/bin" >> "$GITHUB_PATH".

On runners that intercept package managers at /usr/bin/ (safe-chain installs a pkg-bundled Node wrapper at /usr/bin/bun), step 2 puts that shim ahead of the real setup-bun-installed bun (/home/runner/.bun/bin/bun) in $PATH.

The post-step then runs:

BUN_BIN="${GITHUB_ACTION_PATH}/bin/bun" [ -x "$BUN_BIN" ] || BUN_BIN="bun" "$BUN_BIN" --no-env-file
--config="${GITHUB_ACTION_PATH}/bunfig.toml"
--tsconfig-override="${GITHUB_ACTION_PATH}/tsconfig.json"
run ${GITHUB_ACTION_PATH}/src/entrypoints/post-buffered-inline-comments.ts

If the pin step's cp succeeded, $BUN_BIN is the real bun and this works. But on these runners, the pin step's command -v bun apparently resolves to the safe-chain shim (because the runner has already configured /usr/bin in PATH at action start), so the cp produces a copy of the shim, not real bun. The shim receives bun's CLI args (--no-env-file ... run <ts>), treats the first non-flag arg as a Node module name, and crashes with MODULE_NOT_FOUND.

The stack trace's pkg/prelude/bootstrap.js is Vercel pkg's runtime — real bun is a Zig binary and would never produce this trace, confirming the binary that ran is a Node-app shim, not real bun.

Suggested fixes (any one)

  1. Pin step: resolve bun via the bundled setup-bun install dir explicitly, not via command -v. E.g. cp "$BUN_INSTALL/bin/bun" "$GITHUB_ACTION_PATH/bin/bun" where $BUN_INSTALL is set by oven-sh/setup-bun. This avoids whatever PATH-shadowed bun the runner provides.
  2. Post-step: use an absolute path that bypasses PATH entirely (you already do this in the main step via ${GITHUB_ACTION_PATH}/bin/bun, but the fallback path "bun" re-introduces the PATH lookup).
  3. PATH-prepend step: append /usr/bin and /bin rather than prepend, so the setup-bun-installed bun stays first. This keeps the security hardening intent (system bins always available) without shadowing tools the action explicitly installed.

Reproduction

Workaround in caller

Set continue-on-error: true on the action step. Substantive review functionality still works (top-level comments are posted by the main step). Inline-comment posting via mcp__github_inline_comment__create_inline_comment is lost (buffered to disk but never flushed to GitHub).