Skip to content

tweakcc 4.3.3: new CJS parse-check breaks all ESM bundles (node --check bundle.cjs) #981

Description

@rgutzen

Summary

tweakcc 4.3.3 fails to apply any customizations to Claude Code installations whose bundle is ESM, because the new parse-check (node --check bundle.cjs) treats the bundle as CommonJS. Every --apply ends in:

✖ The patched bundle failed to parse. Your customizations were not applied; Claude Code is running the original unmodified version.
import{createRequire as vP5}from"node:module";var MP5=Object.create;...
^

SyntaxError: Cannot use import statement outside a module

Root cause

Claude Code's cli.js has shipped as an ES module ("type": "module" in package.json, top-level import{...}from"...") since v1.0.20 — this is not new.

The node --check bundle.cjs parse-check is new in 4.3.3. 4.3.2 has no parse-check at all (I unpacked tweakcc@4.3.2 and confirmed no mkdtemp/bundle.cjs/PatchedBundleParseError code exists). Because the check writes the bundle to bundle.cjs, Node parses it with CommonJS semantics and rejects the top-level import statements even when the bundle is completely valid ESM.

Verified directly:

# claude-code 2.1.112 cli.js (valid ESM)
cp cli.js /tmp/test.mjs && node --check /tmp/test.mjs   # exit 0
cp cli.js /tmp/test.cjs && node --check /tmp/test.cjs   # SyntaxError: Cannot use import statement outside a module

So the failure is entirely a function of the .cjs extension tweakcc 4.3.3 uses, not the content of the bundle or the user's customizations.

Reproduction

npm i -g @anthropic-ai/claude-code@2.1.112   # last version shipping cli.js (bin: cli.js)
npx tweakcc@4.3.3 --apply --yes
# => "Patched bundle failed to parse"

Note: npx tweakcc@4.3.2 --apply --yes on the exact same install succeeds (patches apply, changesApplied: true).

Two related issues

  1. Parse check must use .mjs (or respect the bundle's "type": "module"), since Claude Code bundles are ESM. Using .cjs guarantees failure.

  2. Native installs (Claude Code ≥ 2.1.113, incl. npm bin/claude.exe) have a separate, still-open breakage: since 2.1.247 the Bun bundle is split into ESM chunks. extractClaudeJsFromNativeInstallation extracts the entry module /$bunfs/root/cli (a ~20 KB stub of import{...}from"/$bunfs/root/chunk-*.js"), while the actual code (and system prompts) live in the separate chunk-*.js modules. Every patch reports "Could not find ... in cli.js", and even the unpatched entry stub fails the .cjs parse-check. The Claude Code 2.1.231 renames the entry module to /$bunfs/root/cli — extraction fails on every native install #945 fix (entry-module rename) is not sufficient for the chunk-split layout — the chunk modules must be read/inlined.

Environment

  • tweakcc 4.3.3 (broken) vs 4.3.2 (works on cli.js installs)
  • Claude Code 2.1.112 (npm, bin: cli.js, "type": "module")
  • Node v26.7.0, Linux x64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions