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
Symptom
On a runner with no renv package cache, the "Restore R packages" step of
test-smokes.ymlfails before any test runs.renv::restore()downloads all145 lockfile packages, installs 140, and never attempts the remaining
five — reporting only circular "dependency failed" messages with no
underlying install error:
Reproduces identically on ubuntu-latest and windows-latest (rules out
compilers/system deps). All five are recorded as normal P3M
Repositoryentries in
tests/renv.lock; their downloads succeed; there is zeroinstall-attempt output for them between "# Installing packages" and the
failure summary.
(
__linux__/noble/lateston Linux),RENV_PATHS_ROOTempty (cache miss).29763939514 / 29763944071 / 29763956751 (all three identical, both OSes).
effe145("tests - updateR 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.ymlon 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()intry()and downgrading therenv::status()$synchronizedcheck to a warning lets the run proceed;the 5 packages are only needed by the docx/screenshot test stack
(
flextable/officer/webshot2/chromote/zipconsumers), so most ofthe 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
renv.lockcontaining only the 5 packages(+ hard deps) on a clean machine/container with empty
RENV_PATHS_ROOT— does it reproduce outside GHA?a fork dispatch)
RENV_CONFIG_INSTALL_TRANSACTIONAL=FALSE(or staged-installsettings) change the behavior?
pattern; file upstream WITH the minimal reprex if unreported.
versions of
zip/officer/flextablefrom beforeeffe145).RENV_PATHS_ROOTpointed at an empty dir) so cache-masked breakagesurfaces on purpose instead of by surprise.
irrelevant, but confirm while reproducing.