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:
Pin bun binary for post-steps—cp <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.Prepend system bin dirs to PATH—echo "/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)
- Pin step: resolve
bunvia the bundled setup-bun install dir explicitly, not viacommand -v. E.g.cp "$BUN_INSTALL/bin/bun" "$GITHUB_ACTION_PATH/bin/bun"where$BUN_INSTALLis set byoven-sh/setup-bun. This avoids whatever PATH-shadowedbunthe runner provides. - 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). - PATH-prepend step: append
/usr/binand/binrather 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
- Runner: any image that installs supply-chain shims at
/usr/bin/for package managers (e.g. a runner withsafe-chainenabled, which installs a pkg-bundled Node wrapper at/usr/bin/bun). - Workflow: any usage of this action with
allowed_non_write_users: "*"(or any non-empty value) set. - Result: action's main step succeeds and posts comments;
Post buffered inline commentspost-step fails withMODULE_NOT_FOUNDforbun.
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).