Summary
transform-files.js reads the ember-source version literally out of package.json and passes it to semver.coerce(). With pnpm catalogs, the value is the literal string catalog:, so coerce() returns null and the codemod dies with TypeError: Cannot read properties of null (reading 'version').
This is the exact bug reported in #113 and fixed in #115, but in a different call site that was added afterwards — so it's a regression rather than a spot the original fix missed.
Reproduction
Verified from scratch against the published ember-vite-codemod@1.9.0.
# 1. A classic (non-Vite) app. ember-cli >= 7 scaffolds Vite by default, so pin 6.
pnpm dlx ember-cli@6.0.1 new my-app --skip-git --skip-install --pnpm --lang en
cd my-app
# 2. Declare ember-source through a pnpm catalog
cat > pnpm-workspace.yaml <<'EOF'
packages:
- '.'
catalog:
ember-source: ~6.0.0
EOF
# package.json: "ember-source": "~6.0.0" -> "ember-source": "catalog:"
npm pkg set devDependencies.ember-source=catalog:
# 3. The 6.0.1 blueprint ships ember-fetch, which the codemod (correctly) rejects.
# Remove it so we reach the actual bug.
npm pkg delete devDependencies.ember-fetch
pnpm install
# 4. Run the codemod
npx ember-vite-codemod@1.9.0 --skip-git --skip-v2-addon
Actual result
⠋ Running code replacements...
✖ Cannot read properties of null (reading 'version')
.../ember-vite-codemod/lib/tasks/transform-files.js:25
emberVersion = coerce(emberVersion).version;
^
TypeError: Cannot read properties of null (reading 'version')
at modifyFiles (.../ember-vite-codemod/lib/tasks/transform-files.js:25:40)
at async run (.../ember-vite-codemod/lib/utils/run.js:17:5)
at async .../ember-vite-codemod/index.js:110:3
Expected result
The codemod completes, resolving the actual installed ember-source version.
Environment
|
|
ember-vite-codemod |
1.9.0 |
| node |
22.21.1 |
| pnpm |
10.33.3 |
| ember-cli |
6.0.1 |
| ember-source |
6.0.1 (via catalog:) |
Root cause
lib/tasks/transform-files.js:17-26:
const packageJSON = JSON.parse(await readFile('package.json', 'utf-8'));
let emberVersion =
packageJSON['devDependencies']['ember-source'] ??
packageJSON['dependencies']['ember-source'];
// downstream transform functions should still function if no ember-source version is provided
// so we only try to coerce the version if there was one detected in the package.json
if (emberVersion) {
emberVersion = coerce(emberVersion).version; // coerce('catalog:') === null
}
The if (emberVersion) guard only defends against absent, not unparseable. catalog: is truthy, so it falls straight into coerce(...).version.
Why this is a regression
So the correct helper already existed in the repo when this code was written; the new call site just didn't use it.
Suggested fix
resolve-version.js already does exactly the right thing, including returning undefined on MODULE_NOT_FOUND.
Summary
transform-files.jsreads theember-sourceversion literally out ofpackage.jsonand passes it tosemver.coerce(). With pnpm catalogs, the value is the literal stringcatalog:, socoerce()returnsnulland the codemod dies withTypeError: Cannot read properties of null (reading 'version').This is the exact bug reported in #113 and fixed in #115, but in a different call site that was added afterwards — so it's a regression rather than a spot the original fix missed.
Reproduction
Verified from scratch against the published
ember-vite-codemod@1.9.0.Actual result
Expected result
The codemod completes, resolving the actual installed
ember-sourceversion.Environment
ember-vite-codemodcatalog:)Root cause
lib/tasks/transform-files.js:17-26:The
if (emberVersion)guard only defends against absent, not unparseable.catalog:is truthy, so it falls straight intocoerce(...).version.Why this is a regression
catalog:; Resolve actual dependency versions #115 (46743d9, "Resolve actual dependency versions") fixed it by addinglib/utils/resolve-version.jsand switchingensure-ember-cli.jsandupdate-package-json.jsto it. Closed 2025-10-30.transform-files.jswas introduced later, on 2026-03-02 in 460db8c ("add compat-inspector support").git merge-base --is-ancestor 460db8c 46743d9confirms 460db8c is a descendant of the fix.So the correct helper already existed in the repo when this code was written; the new call site just didn't use it.
Suggested fix
resolve-version.jsalready does exactly the right thing, including returningundefinedonMODULE_NOT_FOUND.