Skip to content

Regression: codemod crashes on catalog: versions again, in transform-files.js (re-introduces #113) #165

Description

@Frank3K

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.

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