error TS2307: Cannot find module '@simplewebauthn/server' or its corresponding type declarations.
naming a package that is right there in package.json. That reads as a broken checkout rather than a missing install, which is why it costs more than it should.
It asked whether node_modulesexisted, which is true for anyone who has ever run the script. So a branch that adds a dependency never installs it: the pull brings a new package.json and lockfile, the script reports dependencies already installed, and the build fails on an import the source is entirely right to make.
The passkeys work surfaced it, adding @simplewebauthn/server to the backend and @simplewebauthn/browser to the frontend. Nothing about it is specific to those — any dependency added on any branch would have done the same, and the failure would have looked equally unrelated to its cause each time.
The fix
Compare timestamps instead. npm writes node_modules/.package-lock.json describing exactly what it put there, so holding that against package-lock.json answers the question actually being asked: is what is installed what is currently asked for.
A pull that changes dependencies makes the lockfile newer and this notices. A pull that does not leaves the check skipping the install exactly as before, which is the whole reason the check exists.
Testing
Both branches exercised against the real working tree:
step: Installing backend dependencies (the lockfile has changed)
...after npm install...
note: backend dependencies are up to date
step: Installing frontend dependencies (the lockfile has changed)
Backend and frontend both build cleanly afterwards.
Fixes the local start failing with:
```
error TS2307: Cannot find module '@simplewebauthn/server' or its corresponding type declarations.
```
naming a package that is right there in `package.json`. That reads as a broken checkout rather than a missing install, which is why it costs more than it should.
## The cause
One line in `Install-IfMissing`:
```powershell
if (Test-Path (Join-Path $Directory 'node_modules')) {
Write-Note "$name dependencies already installed"
return
}
```
It asked whether `node_modules` **existed**, which is true for anyone who has ever run the script. So a branch that *adds* a dependency never installs it: the pull brings a new `package.json` and lockfile, the script reports dependencies already installed, and the build fails on an import the source is entirely right to make.
The passkeys work surfaced it, adding `@simplewebauthn/server` to the backend and `@simplewebauthn/browser` to the frontend. Nothing about it is specific to those — any dependency added on any branch would have done the same, and the failure would have looked equally unrelated to its cause each time.
## The fix
Compare timestamps instead. npm writes `node_modules/.package-lock.json` describing exactly what it put there, so holding that against `package-lock.json` answers the question actually being asked: **is what is installed what is currently asked for.**
A pull that changes dependencies makes the lockfile newer and this notices. A pull that does not leaves the check skipping the install exactly as before, which is the whole reason the check exists.
## Testing
Both branches exercised against the real working tree:
```
step: Installing backend dependencies (the lockfile has changed)
...after npm install...
note: backend dependencies are up to date
step: Installing frontend dependencies (the lockfile has changed)
```
Backend and frontend both build cleanly afterwards.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Starting the stack locally failed to build with four copies of
error TS2307: Cannot find module '@simplewebauthn/server'
naming a package that is right there in package.json. That reads as a broken checkout rather than a missing install, which is why it costs more than it should.
The cause is one line in Install-IfMissing. It asked whether node_modules existed and returned early if it did, which is true for anyone who has ever run the script. So a branch that ADDS a dependency never installs it: the pull brings a new package.json and a new lockfile, the script says dependencies already installed, and the build then fails on an import the source is entirely right to make.
The passkeys work is what surfaced it, adding @simplewebauthn/server to the backend and @simplewebauthn/browser to the frontend, but nothing about it is specific to those. Any dependency added on any branch would have done the same, and the failure would have looked equally unrelated to its cause each time.
It now compares timestamps instead. npm writes node_modules/.package-lock.json describing exactly what it put there, so holding that against package-lock.json answers the question actually being asked: is what is installed what is currently asked for. A pull that changes dependencies makes the lockfile newer and this notices; a pull that does not leaves the check skipping the install exactly as before, which is the whole reason the check exists.
Both branches were exercised against the real working tree: stale before installing, up to date after.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes the local start failing with:
naming a package that is right there in
package.json. That reads as a broken checkout rather than a missing install, which is why it costs more than it should.The cause
One line in
Install-IfMissing:It asked whether
node_modulesexisted, which is true for anyone who has ever run the script. So a branch that adds a dependency never installs it: the pull brings a newpackage.jsonand lockfile, the script reports dependencies already installed, and the build fails on an import the source is entirely right to make.The passkeys work surfaced it, adding
@simplewebauthn/serverto the backend and@simplewebauthn/browserto the frontend. Nothing about it is specific to those — any dependency added on any branch would have done the same, and the failure would have looked equally unrelated to its cause each time.The fix
Compare timestamps instead. npm writes
node_modules/.package-lock.jsondescribing exactly what it put there, so holding that againstpackage-lock.jsonanswers the question actually being asked: is what is installed what is currently asked for.A pull that changes dependencies makes the lockfile newer and this notices. A pull that does not leaves the check skipping the install exactly as before, which is the whole reason the check exists.
Testing
Both branches exercised against the real working tree:
Backend and frontend both build cleanly afterwards.
🤖 Generated with Claude Code
Starting the stack locally failed to build with four copies of error TS2307: Cannot find module '@simplewebauthn/server' naming a package that is right there in package.json. That reads as a broken checkout rather than a missing install, which is why it costs more than it should. The cause is one line in Install-IfMissing. It asked whether node_modules existed and returned early if it did, which is true for anyone who has ever run the script. So a branch that ADDS a dependency never installs it: the pull brings a new package.json and a new lockfile, the script says dependencies already installed, and the build then fails on an import the source is entirely right to make. The passkeys work is what surfaced it, adding @simplewebauthn/server to the backend and @simplewebauthn/browser to the frontend, but nothing about it is specific to those. Any dependency added on any branch would have done the same, and the failure would have looked equally unrelated to its cause each time. It now compares timestamps instead. npm writes node_modules/.package-lock.json describing exactly what it put there, so holding that against package-lock.json answers the question actually being asked: is what is installed what is currently asked for. A pull that changes dependencies makes the lockfile newer and this notices; a pull that does not leaves the check skipping the install exactly as before, which is the whole reason the check exists. Both branches were exercised against the real working tree: stale before installing, up to date after. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>