pnpm
pnpm copied to clipboard
Can't use specifier for a snapshot dependency in the lock file
Verify latest release
- [X] I verified that the issue exists in the latest pnpm release
pnpm version
9.1.2
Which area(s) of pnpm are affected? (leave empty if unsure)
Dependencies resolver, Lockfile
Link to the code that reproduces this issue or a replay of the bug
https://github.com/gabrielmfern/pnpm-resolution-issue-repro
Reproduction steps
- Check that the resolution of
@types/reactfortypes-react-domis an exact version not a specifier - Try adding a specifier into the snapshot for
types-react-domby changing it to:
[email protected]:
dependencies:
'@types/react':
specifier: npm:types-react@rc
version: [email protected]
- Confirm that it errors when running
pnpm install
Describe the Bug
I was specifically trying to upgrade the React's types package to React 19 by changing the dependencies with something like:
{
"devDependencies": {
"@types/react": "npm:types-react@rc",
"@types/react-dom": "npm:types-react-dom@rc",
}
}
But, since types-react-dom has @types/react as a dependency, I would expect pnpm to resolve into using types-react as @types/react instead of a published version of @types/react, but, it apparently resolves into using another resolved version of @types/react in my workspace.
After noticing this happening, I tried going through the lock file to see if I could manually solve the resolution of it, which was something like:
importers:
project:
devDependencies:
'@types/react':
specifier: npm:types-react@rc
version: [email protected]
'@types/react-dom':
specifier: npm:types-react-dom@rc
version: [email protected]
snapshots:
[email protected]:
dependencies:
'@types/react': 18.2.47
And then I tried changing the snapshot to the following to fix the issue:
importers:
project:
devDependencies:
'@types/react':
specifier: npm:types-react@rc
version: [email protected]
'@types/react-dom':
specifier: npm:types-react-dom@rc
version: [email protected]
snapshots:
[email protected]:
dependencies:
- '@types/react': 18.2.47
+ '@types/react':
+ specifier: npm:types-react@rc
+ version: [email protected]
And I was met with the following error:
ERROR ref.startsWith is not a function
pnpm: ref.startsWith is not a function
at refsByPkgNames.reduce.depPaths (/corepack/pnpm/9.1.2/dist/pnpm.cjs:137562:17)
at Array.reduce (<anonymous>)
at parseDepRefs (/corepack/pnpm/9.1.2/dist/pnpm.cjs:137561:29)
at pkgAllDeps (/corepack/pnpm/9.1.2/dist/pnpm.cjs:137530:83)
at pickPkgsWithAllDeps (/corepack/pnpm/9.1.2/dist/pnpm.cjs:137485:7)
at filterLockfileByImportersAndEngine (/corepack/pnpm/9.1.2/dist/pnpm.cjs:137453:52)
at filterLockfileByEngine (/corepack/pnpm/9.1.2/dist/pnpm.cjs:137444:14)
at headlessInstall (/corepack/pnpm/9.1.2/dist/pnpm.cjs:174676:74)
at async _install (/corepack/pnpm/9.1.2/dist/pnpm.cjs:192101:33)
at async mutateModules (/corepack/pnpm/9.1.2/dist/pnpm.cjs:191966:23)
Expected Behavior
I would expect that it either would work after changing the lock file, or it would be resolving it properly based on the current package instead of the version in the workspace or the latest version.
Which Node.js version are you using?
20.11.1
Which operating systems have you used?
- [ ] macOS
- [ ] Windows
- [X] Linux
If your OS is a Linux based, which one it is? (Include the version if relevant)
Arch Linux
Can't use specifier for a snapshot dependency in the lock file
This is not your real problem, your real problem is that you want to use types-react in place of @types/react, correct?
Is overrides sufficient?
{
"pnpm": {
"overrides": {
"@types/react": "npm:types-react@rc"
}
}
}
Hey @KSXGitHub
This is not your real problem, your real problem is that you want to use types-react in place of @types/react, correct?
Sort of, yes. More specifically, it is that the resolved dependency of @types/react for types-react-dom is not being resolved as types-react.
Is overrides sufficient?
I have tried overrides, they are enabled on the repro I made actually, but it doesn't make any difference.
My thinking, coming from someone unfamiliar with pnpm internals, is that pnpm can't resolve it from the override precisely because it can't use specifiers on snapshot dependencies.
overrides should be at top-level package.json.
The documentation clearly states:
Note that the overrides field can only be set at the root of the project.
Oh, didn't know that. Thanks for the heads-up. Still, though, it resolves to a set version instead of the specifier:
[email protected]:
dependencies:
'@types/react': 18.3.3
Still, though, it resolves to a set version instead of the specifier
I have cloned your repo and set pnpm.overrides then run pnpm install. This is the result:
I suspect you set overrides instead of pnpm.overrides. You should double check. Is your overrides inside a pnpm object?
You are right, I misconfigured it again, sorry for not reading the docs thoroughly enough on this, but, the issue still seems to persist.
Also, from the part of the lock file you shared, I still think I haven't got my issue across clearly enough though, so let me go through it again. types-react-dom has a dependency on @types/react, specifically it has "@types/react": "*". The problem, then, is that the version that pnpm is resolving for this specific dependency (18.3.3) is not the same as the override (npm:types-react@rc).
My initial thinking was that pnpm should resolve it from my own specified version for @types/react (which is npm:types-react@rc), but I guess that is out of pnpm's scope. This not working with the override still seems to me like an issue, though, wonder what you think about this. Let me know if I'm being clear enough.
Small note on when the issue happens
The issue doesn't actually seem to happen when you depend directly on types-react-dom. The snapshots section I've been mentioning then looks like:
[email protected]:
dependencies:
'@types/react': [email protected]
Which I guess I can manually add in as a workaround. But this is what it is supposed to be resolved to when the proper override is configured.
@gabrielmfern I think I get what you mean: You are referring to the fact that even though @types/react has been overridden, types-react-dom still depends on @types/react instead of types-react. As seen in the snapshot section of the lockfile:
snapshots:
# ...
[email protected]:
dependencies:
'@types/react': 18.3.3
I have inspect the problem and found that the problem is from with-react-19/package.json. You may change it to the following:
{
"name": "with-react-19",
"devDependencies": {
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0"
}
}
The snapshots in the lockfile should now be as you desired:
snapshots:
[email protected]: {}
[email protected]:
dependencies:
'@types/react': [email protected]
[email protected]:
dependencies:
csstype: 3.1.3
@zkochan I see that overrides doesn't affect dependencies of dependencies specified with npm: scheme. Is this intended behavior?
Yeah, it works! That's interesting, but really unintuitive, why does this even work?
@KSXGitHub probably not intended.
It is interesting that I can't reproduce the bug with clean install.
So the bug only appears if there was a lockfile from previous install (without pnpm.overrides). Removing the lockfile and run pnpm install again and it will work properly.
Actually, both the lockfile and the node_modules directory have to be removed to workaround this bug.
Removing only the lockfile but not node_modules then run pnpm install would create a different lockfile from before setting overrides, but still not the same one as complete clean install. The complete clean install version is the most minimal.