Skip to content

CI: cold-cache renv::restore() fails on 5-package cluster — test setup unusable on forks / fresh caches #14711

Description

@cderv

Symptom

On a runner with no renv package cache, the "Restore R packages" step of
test-smokes.yml fails before any test runs. renv::restore() downloads all
145 lockfile packages, installs 140, and never attempts the remaining
five — reporting only circular "dependency failed" messages with no
underlying install error:

Successfully installed 140 packages in 46 seconds.

The following package(s) were not installed successfully:
- [chromote]: dependency failed (zip)
- [flextable]: dependency failed (flextable, webshot2, officer)
- [officer]: dependency failed (flextable, webshot2, zip)
- [webshot2]: dependency failed (chromote)
- [zip]: dependency failed (flextable, webshot2)

Error: failed to install "chromote", "flextable", "officer", "webshot2", "zip"

Reproduces identically on ubuntu-latest and windows-latest (rules out
compilers/system deps). All five are recorded as normal P3M Repository
entries in tests/renv.lock; their downloads succeed; there is zero
install-attempt output for them between "# Installing packages" and the
failure summary.

  • Environment: renv 1.2.3, R 4.5.2 (lockfile records 4.5.1), P3M binary repo
    (__linux__/noble/latest on Linux), RENV_PATHS_ROOT empty (cache miss).
  • Evidence runs (fork, workflow_dispatch): cderv/quarto-cli runs
    29763939514 / 29763944071 / 29763956751 (all three identical, both OSes).
  • The affected versions entered the lockfile in effe145 ("tests - update
    R env").

Why upstream CI doesn't see it

Every upstream run restores these packages from a warm renv package
cache
(link from cache, no install scheduling), so the failure is latent.
Any cold-cache environment hits it deterministically: new forks, cache
eviction, a runner OS image bump that changes the cache key, or new OS
targets (e.g. future macOS built-version legs). Upstream CI is one
cache-cleanup away from going red in setup.

Reproduction

Dispatch test-smokes.yml on any fork (or clear the
*-renv-* Actions caches upstream) and watch the "Restore R packages"
step. No code changes needed.

Workaround (verified)

Wrapping renv::restore() in try() and downgrading the
renv::status()$synchronized check to a warning lets the run proceed;
the 5 packages are only needed by the docx/screenshot test stack
(flextable/officer/webshot2/chromote/zip consumers), so most of
the suite runs fine without them. Not proposed as the fix — just triage.

Root-cause hypothesis (UNVERIFIED)

The circular "dependency failed" set with no attempted install looks like
renv's install scheduler refusing/deadlocking on a dependency cycle among
this cluster (possibly via Suggests edges, e.g. flextable ⇄ officer,
flextable → webshot2 → chromote). Needs confirmation.

Investigation checklist

  • Minimal reprex: a stripped renv.lock containing only the 5 packages
    (+ hard deps) on a clean machine/container with empty
    RENV_PATHS_ROOT — does it reproduce outside GHA?
  • Does renv > 1.2.3 fix it? (pin newer renv in the bootstrap and re-run
    a fork dispatch)
  • Does RENV_CONFIG_INSTALL_TRANSACTIONAL=FALSE (or staged-install
    settings) change the behavior?
  • Search rstudio/renv issues for the "dependency failed" circular
    pattern; file upstream WITH the minimal reprex if unreported.
  • Check whether a version pin sidesteps it (e.g. previous lockfile
    versions of zip/officer/flextable from before effe145).
  • Consider a CI guard: a scheduled cold-cache canary job (restore with
    RENV_PATHS_ROOT pointed at an empty dir) so cache-masked breakage
    surfaces on purpose instead of by surprise.
  • Lockfile records R 4.5.1, CI installs 4.5.2 — almost certainly
    irrelevant, but confirm while reproducing.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions