renv Issues
So far there’s just one thing worth calling out:
When installing packages from GitHub, prefer using a commit SHA (not a PR ref such as
e.g. remotes::github_pull(1353)):
remotes::install_github(
"g6t/g6tr",
ref = "b84b44e909b725332484f88f6f18bb14114aae88", # preferred: full commit SHA
subdir = "packages/g6tr.lx"
)
PR refs are temporary Git references. Once a PR is merged/closed, GitHub drops that
ref, and renv can no longer restore that exact package source later (even though the
PR page still exists).
Ideally, before merging a project PR, make sure your renv.lock does not record GitHub
PR refs. In practice this is easy to forget, so the safer default is: if you need to
install from GitHub, pin the install to a specific commit SHA (the 40-character hash
shown on the commit page). Unlike PR refs, a commit SHA remains restorable after the PR
is merged.
How to get the commit SHA:
- Open the PR on GitHub and click the Commits tab.
- Scroll to the bottom to the latest commit and copy its full SHA (40 characters) using the copy button next to the hash.
Default renv behaviour is pretty strict.
- Most issues show up during
renv::restore(). By default,renvwill either restore everything according to the lockfile or nothing: it restores into a temporary library and wipes all progress if something fails. - Also, the only exposed way to change what’s in
renv.lock(read: to tellrenv::restore()to install something differently) is viarenv::snapshot(). And by defaultsnapshot()records your full current library state, which isn’t what you want when you’re in the middle of troubleshooting.
Fortunately, you can loosen things up a bit. Both functions have parameters that give you some wiggle room:
transactional restore
renv::restore() is transactional by default (transactional = TRUE): it
restores into a temporary library and only swaps it into place if everything
succeeds. If something fails, you often end up re-running the restore from
scratch.
If you’re troubleshooting and want to keep partial progress between attempts, run:
renv::restore(transactional = FALSE)
This restores directly into the project library, so you can retry without losing everything.
update mode of snapshotting
If renv::restore() errors, in most cases it means the installation source
recorded in the lockfile is no longer reachable, broken, or the lockfile simply
doesn’t have usable instructions for that package.
In those cases, the fix is usually:
- install the package manually from a working source (often whatever the latest version is on CRAN is fine, but be aware it can introduce breaking changes), then
- record just that change into the lockfile with
renv::snapshot(update = TRUE)and thepackagesargument.
The update = TRUE flag is critical. Without it, renv rewrites the lockfile
to match the current library, which is often nearly empty after a failed
renv::restore() (for example: only the package you just installed plus its
deps), and you lose the rest of the records. Also make sure you specify the
package name in packages, because in some setups renv may otherwise ignore
it.
When prompted by renv::snapshot, choose option 1 (“Snapshot, just using
the currently installed packages.”).
So the process becomes:
- Run
renv::restore(transactional = FALSE). - If a package fails to install, install it manually, then record it with
renv::snapshot(packages = "package_name", update = TRUE). Then go back to 1.
There are various reasons why the lockfile instructions for a specific package may not work. Below are a few common cases and what they tend to look like in practice.
failed to find source for 'Biobase 2.68.0' in package repositories
This happens fairly often with Biobase. The exact reason is still unclear.
There may be a robust way to prevent it, but we don’t have it nailed down yet.
The fix is the same. The only special note is that you need the Bioc:: prefix
when installing it:
renv::install("Bioc::Biobase")
renv::snapshot(packages = "Biobase", update = TRUE)
Error: error testing if 'waldo' can be loaded [error code 1]
Traceback (most recent calls last):
... typically useless error traceback ...
Reason: unclear. Installing the latest version from CRAN has helped in the past.
* installing *source* package ‘g6tr.datalake’ ...
** using staged installation
** R
** data
*** moving datasets to lazyload DB
** byte-compile and prepare package for lazy loading
Error in loadNamespace(j <- i[[1L]], c(lib.loc, .libPaths()), versionCheck = vI[[j]]) :
there is no package called ‘googlesheets4’
Calls: <Anonymous> ... loadNamespace -> withRestarts -> withOneRestart -> doWithOneRestart
Execution halted
ERROR: lazy loading failed for package ‘g6tr.datalake’
...
In this example, the real issue is that googlesheets4 isn’t available when
installing g6tr.datalake. Even if googlesheets4 is recorded in the lockfile,
renv may not install it early enough if the dependency isn’t declared for that
version of g6tr.datalake (for example, missing from its DESCRIPTION file).
To fix it, install googlesheets4 first and continue, or install the newest
version from CRAN and record it in the lockfile.
GitHub record for package 'g6tr.conjoint' has no recorded 'RemoteSha'
This usually means the package was installed from a GitHub PR ref that no longer exists. As outlined in the “Installing packages from GitHub” chapter, to prevent this in the future, only install from GitHub via a commit ref. To fix it, you can either find the corresponding commit ref for that (already merged) PR, or just install the newest version from CRAN.
This can happen either during renv::restore() or while installing a package. You may see errors like:
Downloading g6tr.dl from GitHub ...
Error: destination path '"/pfs/R/renv/root/source/github/g6tr.dl/renv-tempfile-112ae5295ed2fb"' is not writable; cannot proceed
RENV_CACHE_MODE is now set for all sessions via the rsession-profile. In testing, this
appears to prevent the error, so it’s not expected to show up going forward (though it
isn’t fully proven yet). It ensures that new cache entries (binary or source) are
group-writable for rstudio-users.
# /etc/rstudio/rsession-profile
export RENV_CACHE_MODE=g+rwX
Root cause: with default settings, renv creates new cache files/folders that are
only writable by the creating user (no group overwrite), which can block others.
If it happens again, first fix permissions on the affected path (or the whole cache).
Then follow up: it means RENV_CACHE_MODE didn’t fully address the issue, so we should
investigate further.
To reset permissions for the entire cache:
sudo chown -R root:rstudio-users /pfs/R/renv
sudo chmod -R 2775 /pfs/R/renv
This will take a while (half an hour or so for each of the commands) because the cache is large.