fix(standalone): savings-check.js crashes on startup (createRequire(undefined) in CJS bundle)#17
Open
jpr5 wants to merge 1 commit into
Open
fix(standalone): savings-check.js crashes on startup (createRequire(undefined) in CJS bundle)#17jpr5 wants to merge 1 commit into
jpr5 wants to merge 1 commit into
Conversation
standalone/savings-check.js is an esbuild CommonJS bundle (standalone/package.json declares "type": "commonjs"), so import.meta is never available at runtime and import_meta.url is always undefined. createRequire(undefined) throws ERR_INVALID_ARG_VALUE on every Node version, so running the script as documented (node savings-check.js) fails immediately on a clean checkout. Fall back to __filename when import.meta.url is absent.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
standalone/savings-check.jscrashes on startup withnode savings-check.js— the exact invocation the README documents. This fixes it with a one-line change.Root cause
standalone/package.jsondeclares"type": "commonjs", so the bundle always runs as CommonJS. esbuild emitsvar import_meta = {}for the bundled@anthropic-ai/claude-agent-sdk(an ESM module that usesimport.meta.url), soimport_meta.urlis alwaysundefinedat runtime:createRequire(undefined)throwsERR_INVALID_ARG_VALUEduring top-level module init. This is version-independent — not tied to any particular Node release.The fix
__filenameis the absolute path of the bundle under CommonJS, whichcreateRequireaccepts. Theimport_meta.url ||prefix preserves correct behavior if the file is ever executed as a real ES module.Red / green proof
RED — unpatched, on a clean download of the committed blob:
Reproduced identically on Node v25.8.0 and Node v20.20.2, confirming it is not version-specific.
GREEN — with the one-line fix, same file, same machine:
Note: don't pipe to
node -The README's
curl ... | node -form fails separately withCannot set property crypto of #<Object> which has only a getter, because in stdin/eval mode the bundle's top-levelvar crypto = require("crypto")collides with Node's read-onlyglobalThis.cryptogetter (Node ≥ 20). Running the file as a file (not stdin-eval) avoids this. Worth updating the install snippet to download-then-run.Two unrelated observations
node_modulesis committed to the repo. The repository is ~1.3 GB largely because of this, which makes clones and forks painfully heavy.node_modulesshould be in.gitignoreand removed from version control — the prebuiltstandalone/bundle is self-contained and doesn't need it shipped in git.The file header's claims are inaccurate as written. The top comment states "No network calls. No writes. No telemetry. No child processes." That is true of the reachable code path from
main()(it only reads~/.claude/projects/*.jsonland writes to stdout). But it is not true of the file: the bundle statically includes@anthropic-ai/claude-agent-sdk(and the wozcore file-concurrency utils), which containfetch(),child_process.execFile, andfswrite/unlink/symlink/rmSynccalls as dead, unreachable code. The capabilities are present in the shipped bytes even though they're never invoked. Consider either scoping the claim to the executed path, or tree-shaking the agent SDK out of this standalone build so the audit claim matches the contents.