Hey I recently investigated a broken CI pipeline of a project using renv.
The issue seems to stem from the package lamW changing between P3M snapshots (although the version number did not change and there were no commits to the project in months).
The obvious solution is to use snapshots instead of a link to latest.
I'm still wondering how this issue is possible. What can change between snapshots and why?
I documented a minimal reproduction of the problem here: renv reproducibility issue · GitHub. Installing lamW version 5.1.9 in an empty project works when using the snapshot from January 23, but fails for a later snapshot because it cannot properly link to RcppParallel:
Thanks for the bug report! The most recent release of RcppParallel (5.1.10) includes some changes in its binary ABI, so this issue most likely implies that:
lamW 5.1.9 itself was built against RcppParallel 5.1.10, but
Your project depends on an older version of RcppParallel, 5.1.9.
I believe the simplest fix here would be to update RcppParallel in your lockfile to 5.1.10. Note that this version is backwards-compatible with packages built against old and new versions of RcppParallel.
Although issues of this form should be rare, you are indeed right that the best way to insulate from these sorts of issues (when package versions are pinned) is to use a specific PPM snapshot.
You're welcome! Thanks for the clarification. That makes a lot of sense.
I was already suspecting that the recent release of RcppParallel 5.1.10 was the culprit,
but I could not connect the dots.
ABI compatibility issues can arise if different packages were built against different versions of a shared dependency. For example, one package may have been built against Rcpp 1.0.6, and another package might have been built against Rcpp 1.0.7. However, because only one version of the Rcpp package can be loaded at a time within an R session, mixing of these two packages might cause issues either on load or at runtime depending on the version of Rcpp available.
It’s worth emphasizing that this is not Rcpp’s fault; a package built against Rcpp 1.0.7 would reasonably expect newer APIs made available by that version of the package would be available at runtime, and that contract would be violated if an older version of Rcpp were installed in the project library. The challenge for renv is that this build-time dependency is not clearly communicated to renv; in general, it is not possible to know what packages (and their versions) a particular package was built against.