heroku-buildpack-nodejs
heroku-buildpack-nodejs copied to clipboard
Yarn v2 installation error Usage Error: Couldn't find the node_modules state file - running an install might help (findPackageLocation)
Describe the bug
Using Yarn v2 workspace (node_modules linker, not PnP), the build will fail if heroku-prebuild
is defined in the root package.json
To Reproduce
Steps to reproduce the behavior:
- Use Yarn v2 workspace
- Define a
heroku-prebuild
script in root package.json. The script could be as simple as:{ "scripts": { "heroku-prebuild": "ls" } }
- Deploy it (tested with
git push heroku main
ordpl --provider=heroku
, it doesn't matter) - Sufficient to see the error
Versions (please complete the following information):
- Heroku Stack:
heroku-20
- Node Version:
14.x
- NPM or Yarn Version:
2.4.0
- Buildpack Version: Latest at the time of writing, Not pinned
Additional context
- If
heroku-prebuild
is not defined, the installation always works. -
NODE_MODULES_CACHE
has been disabled or enabled, the error persists. -
NPM_CONFIG_PRODUCTION
andYARN_PRODUCTION
has been unset as per the official migration guide, the error still persists - No other buildpacks interfering
- No output seen on the log for the
heroku-prebuild
script (suggesting that maybe it wasn't even run)
Log output (trimmed):
-----> Node.js app detected
-----> Creating runtime environment
NPM_CONFIG_LOGLEVEL=error
USE_YARN_CACHE=true
NODE_VERBOSE=false
NODE_ENV=production
NODE_MODULES_CACHE=false
-----> Installing binaries
engines.node (package.json): unspecified
engines.npm (package.json): unspecified (use default)
engines.yarn (package.json): unspecified (use default)
Resolving node version 14.x...
Downloading and installing node 14.16.0...
Using default npm version: 6.14.11
Resolving yarn version 1.22.x...
Downloading and installing yarn (1.22.10)
Using yarn 2.4.0
-----> Restoring cache
Caching has been disabled because NODE_MODULES_CACHE=false
-----> Prebuild
Running heroku-prebuild (yarn)
Usage Error: Couldn't find the node_modules state file - running an install might help (findPackageLocation)
$ yarn run [--inspect] [--inspect-brk] <scriptName> ...
-----> Build failed
We're sorry this build is failing! You can troubleshoot common issues here:
https://devcenter.heroku.com/articles/troubleshooting-node-deploys
having the same issue, any insight into this?
It seems like when we define heroku-prebuild
hook in package.json, yarn run <script>
will be called
Since Yarn v2 it seems impossible to call yarn run <script>
before installing dependencies and since heroku-prebuild
is called before dependencies are installed... you can guess what's next, the error reported by @jasonlimantoro .
adding a note for devs in the future with similar headaches...
I kept getting this error even after running yarn install
but it turned out to be caused by inconsistent nodeLinker
in .yarnrc.yml
it was a sub project, which was a git submodule and a yarn workspace, configured as nodeLinker: node-modules
but the worktree .yarnrc.yml was configured for nodeLinker: pnp
(default)
fixed by removing nodeLinker: node-modules
and running yarn install
I was running into the same issue and came across this workaround: https://github.com/yarnpkg/berry/issues/2701#issuecomment-901816600 It uses a yarn plugin and hook to allow particular scripts to run without the expected node_modules state. For example, we needed a heroku-prebuild
script to set up Yarn authentication to a private registry before a yarn install
has occurred.
// .yarn/plugins/override-state.js
const ALLOWED_SCRIPTS = ['heroku-prebuild'];
const NODE_MODULES = 'node_modules';
const STATE_FILE = '.yarn-state.yml';
module.exports = {
name: `plugin-override-state`,
factory: require => ({
hooks: {
async setupScriptEnvironment(project, scriptEnv) {
if (
scriptEnv != null &&
ALLOWED_SCRIPTS.find(
script => script == scriptEnv.npm_lifecycle_event,
) != null
) {
if (project.configuration.get(`nodeLinker`) === `node-modules`) {
const stateFile = [project.cwd, NODE_MODULES, STATE_FILE].join('/');
const fs = require('fs');
if (!fs.existsSync(stateFile)) {
console.log(
'Detected command allowed in stateless environment and state file is missing.',
);
console.log('Generating empty state file...');
fs.mkdirSync(require('path').dirname(stateFile), {
recursive: true,
});
fs.appendFileSync(stateFile, '# Autogenerated\n', { flag: 'w+' });
fs.appendFileSync(stateFile, '__metadata:\n');
fs.appendFileSync(stateFile, ' version: 1\n');
fs.appendFileSync(stateFile, ' nmMode: classic\n');
}
}
}
},
},
}),
};
Enabled with
# .yarnrc.yml
plugins:
- .yarn/plugins/override-state.js
@ferm10n why is using node-linker
an issue here?
I had this issue while trying to run Storybook in Backstage repo, fixed it by running the install command directly inside the Storybook folder, not sure why that is the only one that breaks given that we have many plugins that work with just the root install.
@ferm10n why is using
node-linker
an issue here?
@simkessy because there's a conflicting source of truth for how to resolve packages. whether it's through node_modules, or through a pnp file.