pnpm install defaults --frozen-lockfile to true when it detects a CI environment, and to false otherwise. That means a lockfile out of sync with package.json fails the CI job with ERR_PNPM_OUTDATED_LOCKFILE Cannot install with "frozen-lockfile" because pnpm-lock.yaml is not up to date with package.json, while the same command on a laptop quietly updates the lockfile.
Detection is based on the CI environment variable, so a local shell with CI=true exported behaves like the pipeline, which is a good way to reproduce the failure before pushing.
The fix is to run pnpm install locally and commit the updated pnpm-lock.yaml. Do not add --no-frozen-lockfile to the CI command: it makes the build resolve fresh versions and removes the guarantee that CI tested what the lockfile pins. If the mismatch is caused by a workspace package version bump, run the install at the workspace root so all projects are updated in one pass.