Skip to content

fix: avoid top-level await in bun-runner so hooks load on Node < 14.8#3061

Open
Kurama2d wants to merge 1 commit into
thedotmack:mainfrom
Kurama2d:fix/node12-top-level-await
Open

fix: avoid top-level await in bun-runner so hooks load on Node < 14.8#3061
Kurama2d wants to merge 1 commit into
thedotmack:mainfrom
Kurama2d:fix/node12-top-level-await

Conversation

@Kurama2d

@Kurama2d Kurama2d commented Jun 25, 2026

Copy link
Copy Markdown

Problem

plugin/scripts/bun-runner.js is an ES module that uses a top-level await:

const stdinData = await collectStdin();

Top-level await is unsupported by the ESM loader of Node < 14.8. On hosts where Claude Code invokes hooks with an older Node — e.g. the Node 12 that ships with Ubuntu 22.04 and many WSL setups — the module fails to load before running anything:

file:///.../claude-mem/.../scripts/bun-runner.js:128
const stdinData = await collectStdin();
                  ^^^^^
SyntaxError: Unexpected reserved word
    at Loader.moduleStrategy (internal/modules/esm/translators.js:133:18)

This breaks every claude-mem hook (e.g. the Stop hook surfaces it as a hook error) for those users.

Fix

Wrap the body after collectStdin() in an async IIFE so await is no longer at module scope. No behavior change on modern Node.

This is the same oldest-Node compatibility concern the file already handles deliberately for optional chaining — see the ?. note above isPluginDisabledInClaudeSettings().

Repro / verification

# Under Node 12:
node --check plugin/scripts/bun-runner.js
  • Before: SyntaxError: Unexpected reserved word
  • After: parses OK (verified on v12.22.9)

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR removes top-level await from the Bun hook runner. The main changes are:

  • Wraps stdin collection and child process startup in an async IIFE.
  • Keeps existing argument handling, stdin forwarding, diagnostics, and exit behavior unchanged.
  • Preserves compatibility with older Node ESM loaders that cannot parse top-level await.

Confidence Score: 5/5

Safe to merge; the change is narrowly scoped to moving existing asynchronous startup logic out of module scope.

The modified file preserves the existing control flow and behavior while improving compatibility with older Node ESM loaders.

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex ran the code on Node 12 at the base revision and observed an exit code of 1 with a SyntaxError: Unexpected reserved word at const stdinData = await collectStdin().
  • T-Rex re-ran the code on Node 12 at head and observed an exit code of 0 with no parse errors.
  • T-Rex also checked Node v20.9.0 at head and observed an exit code of 0 with no parse errors.

View all artifacts

T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "fix: avoid top-level await in bun-runner..." | Re-trigger Greptile

bun-runner.js is an ES module that uses a top-level `await collectStdin()`.
Top-level await is unsupported by the ESM loader of Node < 14.8, so on hosts
where Claude Code invokes hooks with an older Node (e.g. the Node 12 shipped
by Ubuntu 22.04 / many WSL setups) the module fails to load with
"SyntaxError: Unexpected reserved word", breaking every claude-mem hook.

Wrap the post-collectStdin body in an async IIFE so `await` is no longer at
module scope. Same oldest-Node compatibility concern already handled in this
file for optional chaining (see the `?.` note above isPluginDisabledInClaudeSettings).

Repro: `node --check plugin/scripts/bun-runner.js` under Node 12 fails before
this change and passes after.
@Kurama2d Kurama2d force-pushed the fix/node12-top-level-await branch from 950e33f to 7bb0672 Compare June 25, 2026 19:33
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.

1 participant