Node ERR_MODULE_NOT_FOUND on ESM Import in CI - Fix Specifier Resolution
ERR_MODULE_NOT_FOUND is the ES module version of "cannot find module". The ESM loader does not guess extensions, so a bare relative import fails to resolve.
What this error means
A program run as ESM (type module or .mjs) throws Error [ERR_MODULE_NOT_FOUND] naming a relative import. The fix that worked under CommonJS (omitting .js) no longer applies.
node:internal/process/esm_loader:97
Error [ERR_MODULE_NOT_FOUND]: Cannot find module
'/home/runner/work/app/app/src/utils' imported from /home/runner/work/app/app/src/index.js
Did you mean to import ./utils.js?Common causes
A relative import without a file extension
Native ESM requires the full path including .js; unlike CommonJS it will not append the extension for you.
Importing a directory without an explicit index file path
ESM does not auto-resolve ./dir to ./dir/index.js, so a directory import fails outright.
How to fix it
Add the explicit file extension
- Change bare relative imports to include the .js extension that the compiled output uses.
- Point directory imports at the concrete index.js file.
- Re-run the job to confirm the loader resolves it.
import { format } from './utils.js';
import config from './config/index.js';How to prevent it
- When compiling TypeScript to ESM, write .js extensions in source imports (or use a resolver that rewrites them) so the emitted code resolves under native ESM in CI.