pak icon indicating copy to clipboard operation
pak copied to clipboard

Error in `res_one_row_df(entries)`: ! `nrow(out)` must equal `1`

Open salim-b opened this issue 5 months ago • 13 comments

Problem

pak::pkg_install(dependencies = TRUE) errors when trying to install the following 189 R packages at once:

pkgs_cran <- c(
    "anesrake",
    "anytime",
    "archive",
    "arrow",
    "asciicast",
    "assertr",
    "available",
    "bench",
    "BFS",
    "blastula",
    "blogdown",
    "bookdown",
    "brio",
    "broom",
    "checkmate",
    "cli",
    "clipr",
    "clock",
    "commonmark",
    "constructive",
    "covr",
    "crayon",
    "crosstalk",
    "crul",
    "curl",
    "daff",
    "datapasta",
    "DBI",
    "deeplr",
    "desc",
    "DescTools",
    "devtools",
    "DiagrammeR",
    "DiagrammeRsvg",
    "dials",
    "diffobj",
    "diffviewer",
    "digest",
    "dm",
    "dplyr",
    "dqrng",
    "DT",
    "duckdb",
    "forcats",
    "fs",
    "gargle",
    "gert",
    "ggeffects",
    "ggforce",
    "ggiraph",
    "ggplot2",
    "ggstream",
    "gh",
    "gitlabr",
    "glue",
    "googledrive",
    "googlesheets4",
    "graphql",
    "gt",
    "gtsummary",
    "haven",
    "heck",
    "hexSticker",
    "hms",
    "htmltools",
    "htmlwidgets",
    "httr2",
    "imager",
    "infer",
    "ISOcodes",
    "janitor",
    "jsonlite",
    "kableExtra",
    "katex",
    "keyring",
    "knitr",
    "komaletter",
    "labelled",
    "languageserver",
    "learnr",
    "lifecycle",
    "listviewer",
    "lobstr",
    "lubridate",
    "magick",
    "magrittr",
    "miniUI",
    "mirt",
    "modeldata",
    "modelr",
    "mongolite",
    "oai",
    "openssl",
    "pak",
    "paletteer",
    "pander",
    "parsedate",
    "parsnip",
    "pins",
    "pkgbuild",
    "pkgcache",
    "pkgdepends",
    "pkgdown",
    "pkgload",
    "pkgsearch",
    "plumber",
    "prettycode",
    "prettyunits",
    "purrr",
    "qpdf",
    "qs",
    "R6",
    "ragg",
    "rcmdcheck",
    "RColorBrewer",
    "Rcpp",
    "RcppTOML",
    "RCurl",
    "readODS",
    "readr",
    "readxl",
    "recipes",
    "remotes",
    "renv",
    "reprex",
    "reticulate",
    "revealjs",
    "rex",
    "rio",
    "rJava",
    "rlang",
    "rmarkdown",
    "RPostgres",
    "rsample",
    "rsconnect",
    "RSelenium",
    "rstudioapi",
    "rsvg",
    "rvest",
    "s2",
    "s3fs",
    "servr",
    "sessioninfo",
    "sf",
    "shiny",
    "showtext",
    "skimr",
    "staplr",
    "stringdist",
    "stringi",
    "stringr",
    "styler",
    "swissparl",
    "testthat",
    "tibble",
    "tidyr",
    "tidyRSS",
    "tidyselect",
    "tidytext",
    "tidyverse",
    "tiff",
    "tinkr",
    "tokenizers",
    "tune",
    "tweenr",
    "uaparserjs",
    "units",
    "urltools",
    "usethis",
    "uuid",
    "V8",
    "vctrs",
    "viridis",
    "visdat",
    "vroom",
    "webshot2",
    "whoami",
    "widyr",
    "withr",
    "workflows",
    "writexl",
    "xfun",
    "xml2",
    "xopen",
    "xslt",
    "yaml",
    "yardstick",
    "yesno",
    "zip"
)

pak::pkg_install(pkg = pkgs_cran,
                 ask = FALSE,
                 dependencies = TRUE)
#> ℹ Loading metadata database
#> ✔ Loading metadata database ... done
#> 
#> Error: ! error in pak subprocess
#> Caused by error in `res_one_row_df(entries)`:
#> ! `nrow(out)` must equal `1`.

Created on 2025-07-27 with reprex v2.1.1

.Last.error then gives:

<callr_error/rlib_error_3_0/rlib_error/error>
Error: 
! error in pak subprocess
Caused by error in `res_one_row_df(entries)`:
! `nrow(out)` must equal `1`.
---
Backtrace:
1. pak::pkg_install(pkg = pkgs_cran, ask = FALSE, dependencies = TRUE)
2. pak:::remote(function(...) get("pkg_install_make_plan", asNamespace("pak"))(...), …
3. err$throw(res$error)
---
Subprocess backtrace:
 1. base::withCallingHandlers(cli_message = function(msg) { …
 2. get("pkg_install_make_plan", asNamespace("pak"))(...)
 3. prop$solve()
 4. private$plan$solve(policy = private$policy)
 5. pkgdepends:::pkgplan_solve(self, private, match.arg(policy))
 6. self$resolve()
 7. pkgdepends:::pkgplan_resolve(self, private)
 8. pkgdepends:::synchronise(self$async_resolve())
 9. asNamespace("pkgcache")$synchronise(...)
10. base::stop(priv$value)
11. global (function (e) …

And additionally warns (because I set options(warnPartialMatchDollar = TRUE)):

Warning message:
In cond$parent : partial match of 'parent' to 'parents'

System info

sessioninfo::session_info(info = "all") is:

─ Session info ────────────────────────────────────────────────────────────────────────────────────
 setting  value
 version  R version 4.5.1 (2025-06-13)
 os       Ubuntu 24.04.2 LTS
 system   x86_64, linux-gnu
 ui       RStudio
 language (EN)
 collate  en_US.UTF-8
 ctype    en_US.UTF-8
 tz       Etc/UTC
 date     2025-07-27
 rstudio  2025.05.1+513 Mariposa Orchid (desktop)
 pandoc   3.7.0.2 @ /var/home/salim/.local/state/pixi/bin/ (via rmarkdown)
 quarto   1.7.32 @ /usr/local/bin/quarto

─ Packages ────────────────────────────────────────────────────────────────────────────────────────
 package     * version    date (UTC) lib source
 brio          1.1.5      2024-04-24 [1] RSPM
 callr         3.7.6      2024-03-25 [1] RSPM (R 4.5.0)
 cli           3.6.5      2025-04-23 [1] RSPM
 clipr         0.8.0      2022-02-22 [1] RSPM
 crayon        1.5.3      2024-06-20 [1] RSPM
 debugme       1.2.0      2024-04-25 [1] RSPM (R 4.5.0)
 digest        0.6.37     2024-08-19 [1] RSPM
 evaluate      1.0.4      2025-06-18 [1] RSPM
 fastmap       1.2.0      2024-05-15 [1] RSPM (R 4.5.0)
 fs            1.6.6      2025-04-12 [1] RSPM
 glue          1.8.0      2024-09-30 [1] RSPM
 htmltools     0.5.8.1    2024-04-04 [1] RSPM
 knitr         1.50       2025-03-16 [1] RSPM
 lifecycle     1.0.4      2023-11-07 [1] RSPM
 magrittr    * 2.0.3      2022-03-30 [1] RSPM
 pak           0.9.0      2025-05-27 [1] RSPM
 pillar        1.11.0     2025-07-04 [1] RSPM
 pkgcache      2.2.4      2025-05-26 [1] RSPM
 pkgconfig     2.0.3      2019-09-22 [1] RSPM (R 4.5.0)
 pkgdepends    0.9.0      2025-05-27 [1] RSPM
 processx      3.8.6      2025-02-21 [1] RSPM (R 4.5.0)
 ps            1.9.1      2025-04-12 [1] RSPM (R 4.5.0)
 R6            2.6.1      2025-02-15 [1] RSPM
 reprex        2.1.1      2024-07-06 [1] RSPM
 rlang       * 1.1.6      2025-04-11 [1] RSPM
 rmarkdown     2.29       2024-11-04 [1] RSPM
 rprojroot     2.0.4.9005 2025-07-27 [1] Github (salim-b/rprojroot@152bfee)
 rstudioapi    0.17.1     2024-10-22 [1] RSPM
 sessioninfo   1.2.3      2025-02-05 [1] RSPM
 testthat      3.2.3      2025-01-13 [1] RSPM
 tibble        3.3.0      2025-06-08 [1] RSPM
 vctrs         0.6.5      2023-12-01 [1] RSPM
 withr         3.0.2      2024-10-28 [1] RSPM
 xfun          0.52       2025-04-02 [1] RSPM
 yaml          2.3.10     2024-07-26 [1] RSPM

 [1] /var/home/salim/.local/share/distrobox/ubuntu-toolbox-salim/.local/lib/r/x86_64-pc-linux-gnu-library/4.5
 [2] /opt/R/4.5.1/lib/R/library
 * ── Packages attached to the search path.

─ External software ───────────────────────────────────────────────────────────────────────────────
 setting        value
 cairo          1.18.0
 cairoFT
 pango          1.52.1
 png            1.6.43
 jpeg           8.0
 tiff           LIBTIFF, Version 4.5.1
 tcl            8.6.14
 curl           8.5.0
 zlib           1.3
 bzlib          1.0.8, 13-Jul-2019
 xz             5.4.5
 deflate        1.19
 PCRE           10.42 2022-12-11
 ICU            74.2
 TRE            TRE 0.8.0 R_fixes (BSD)
 iconv          glibc 2.39
 readline       8.2
 BLAS           /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
 lapack         /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so
 lapack_version 3.12.0

─ Python configuration ────────────────────────────────────────────────────────────────────────────
 Python is not available

───────────────────────────────────────────────────────────────────────────────────────────────────

getOption("repos") is:

                                         CRAN 
"https://p3m.dev/cran/__linux__/noble/latest"

Further observations

  • When splitting pkgs_cran in half (pkgs_cran[1:95] and pkgs_cran[95:189]), installing each half works fine, i.e. doesn't trigger the error.

  • Setting dependencies = FALSE also avoids triggering the error.

salim-b avatar Jul 27 '25 19:07 salim-b

I can't reproduce this.

When splitting pkgs_cran in half (pkgs_cran[1:95] and pkgs_cran[95:189]), installing each half works fine, i.e. doesn't trigger the error.

That's weird, because some suggested dependencies of your package list are not CRAN packages, e.g. RDCOMClient, so you can't install that from CRAN.

Setting dependencies = FALSE also avoids triggering the error.

dependencies = TRUE is a bad idea in general, because it installs development dependencies of packages, which might not be available on CRAN.

If you want to install the subset that is available, then this might work, assuming the original bug does not happen:

pak::pkg_install(pkg = c(pkgs_cran, "*=?ignore-unavailable"),
                 ask = FALSE,
                 dependencies = TRUE)

gaborcsardi avatar Jul 27 '25 20:07 gaborcsardi

I can't reproduce this.

On what system? Did you also test Ubuntu 24.04 x86_64?

dependencies = TRUE is a bad idea in general, because it installs development dependencies of packages, which might not be available on CRAN.

I understand that. But I wanted to report the bug nevertheless.

Thanks for the hint about "*=?ignore-unavailable".

salim-b avatar Jul 27 '25 21:07 salim-b

I can't reproduce this.

On what system? Did you also test Ubuntu 24.04 x86_64?

Yes.

FROM ubuntu:24.04
RUN apt update
RUN apt install -y curl
RUN curl -L https://rig.r-pkg.org/deb/rig.gpg -o /etc/apt/trusted.gpg.d/rig.gpg
RUN echo "deb http://rig.r-pkg.org/deb rig main" > /etc/apt/sources.list.d/rig.list
RUN apt update
RUN apt install r-rig
RUN rig add release

gaborcsardi avatar Jul 28 '25 06:07 gaborcsardi

We are having a similar issue, but only when using our internal Posit Package Manager. The reproducible example goes like this:

FROM rocker/tidyverse:4.5
# certificates
ADD <...>  /usr/local/share/ca-certificates/
RUN update-ca-certificates
ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
RUN install2.r pak
ENV PPM=<url>
RUN echo "options(repos = c(ppm = '$PPM'))" >>"$R_HOME"/etc/Rprofile.site
RUN git clone https://github.com/bedapub/ribiosIO.git /src
RUN cd /src && Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'
RUN rm -rf /src
RUN git clone https://github.com/bedapub/ribiosArg.git /src
RUN cd /src && Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'

The error looks like this:

error message
STEP 15/15: RUN Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'
! Using bundled GitHub PAT. Please add your own PAT using `gitcreds::gitcreds_set()`.

✔ Updated metadata database: 3.27 MB in 9 files.

ℹ Updating metadata database
✖ Updating metadata database ... failed

Error: 
! error in pak subprocess
Caused by error in `res_one_row_df(entries)`:
! `nrow(out)` must equal `1`.
---
Backtrace:
1. pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)
2. pak:::remote(function(...) { …
3. err$throw(res$error)
---
Subprocess backtrace:
 1. base::withCallingHandlers(cli_message = function(msg) { …
 2. get("local_install_dev_deps_make_plan", asNamespace("pak"))(...)
 3. prop$solve()
 4. private$plan$solve(policy = private$policy)
 5. pkgdepends:::pkgplan_solve(self, private, match.arg(policy))
 6. self$resolve()
 7. pkgdepends:::pkgplan_resolve(self, private)
 8. pkgdepends:::synchronise(self$async_resolve())
 9. asNamespace("pkgcache")$synchronise(...)
10. base::stop(priv$value)
11. global (function (e) …
Execution halted
Error: building at STEP "RUN Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'": while running runtime: exit status 1

Necessary conditions to reproduce the error:

  • internal PPM enabled
  • it will always fail on the second package upon building, if I remove the first installation statement the error disappears.

It only started failing a few days ago, and I do not understand why. Using an older PPM snapshot will still trigger an error; so it's not the package versions it seems. The PPM software version is also from April.

I understand that this is very difficult to debug like this. Are there any debug options you could suggest?

idavydov avatar Nov 03 '25 16:11 idavydov

In our case there is an offending entry which looks something like this:

Package: pkg
Version: 0.8.1
Depends: R (>= 3.5.0)
NeedsCompilation: no
License: BSD_3_clause + file LICENSE
SystemRequirements: XXX
        (https://xxx.org/)
 

There's a whitespace on the last line. So it's "SystemRequirements: XXX\n (https://xxx.org/)\n \n". I am not sure if this violates how the PACKAGES file should look like or not.

Now I should be able to make a reproducible example. Would you need it or this is a malformed PACKAGES file?

idavydov avatar Nov 04 '25 09:11 idavydov

It is a malformed file, but pak should handle it better.

gaborcsardi avatar Nov 04 '25 09:11 gaborcsardi

Thanks, then here's a reproducible example:

Dockerfile:

FROM rocker/tidyverse:4.5
RUN install2.r pak
RUN git clone https://github.com/bedapub/ribiosIO.git /src
RUN cd /src && Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'
RUN rm -rf /src
RUN git clone https://github.com/bedapub/ribiosArg.git /src
RUN echo "options(repos = c(repo = 'file:///repo'))" >>"$R_HOME"/etc/Rprofile.site
ADD https://gist.githubusercontent.com/idavydov/0bfcdd07a0cba786ea08b83dcd84cf27/raw/05c6ea718e89c696e5177632a0b9419b90ecf83e/PACKAGES \
  /repo/src/contrib/PACKAGES
RUN cd /src && Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'

See PACKAGES.

Output of build:

STEP X/X: RUN cd /src && Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'
! Using bundled GitHub PAT. Please add your own PAT using `gitcreds::gitcreds_set()`.

✔ Updated metadata database: 3.25 MB in 9 files.

ℹ Updating metadata database
✖ Updating metadata database ... failed

Error: 
! error in pak subprocess
Caused by error in `res_one_row_df(entries)`:
! `nrow(out)` must equal `1`.
---
Backtrace:
1. pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)
2. pak:::remote(function(...) { …
3. err$throw(res$error)
---
Subprocess backtrace:
 1. base::withCallingHandlers(cli_message = function(msg) { …
 2. get("local_install_dev_deps_make_plan", asNamespace("pak"))(...)
 3. prop$solve()
 4. private$plan$solve(policy = private$policy)
 5. pkgdepends:::pkgplan_solve(self, private, match.arg(policy))
 6. self$resolve()
 7. pkgdepends:::pkgplan_resolve(self, private)
 8. pkgdepends:::synchronise(self$async_resolve())
 9. asNamespace("pkgcache")$synchronise(...)
10. base::stop(priv$value)
11. global (function (e) …
Execution halted
Error: building at STEP "RUN cd /src && Rscript -e 'pak::local_install_dev_deps(upgrade = FALSE, dependencies = NA)'": while running runtime: exit status 1

idavydov avatar Nov 04 '25 10:11 idavydov

It appears that ‘pkgcache’ fails to parse PACKAGE DCF files that contain empty lines with whitespace. read.dcf can read the same file, so there’s an inconsistency between the native R installation mechanism and the package resolution mechanism used by ‘pak’. From our investigation this seems to be related to (/ might cause) the above issue, because the PACKAGE file of our private PPM instance has such a whitespace line in it:

pkgs = list(
  c(Package = 'foo', Version = '1.0.0', Depends = 'R (>= 3.5.0)', Imports = 'utils', NeedsCompilation = 'no', License = 'GPL'),
  c(Package = 'bar', Version = '1.0.0', Depends = 'R (>= 3.5.0)', Imports = 'foo', NeedsCompilation = 'no', License = 'GPL')
)

tmp = tempfile()
write.dcf(do.call(rbind, pkgs), file = tmp)

pkgcache::parse_packages(tmp)
# # A data frame: 2 × 6
#   Package Version Depends      Imports NeedsCompilation License
#   <chr>   <chr>   <chr>        <chr>   <chr>            <chr>  
# 1 foo     1.0.0   R (>= 3.5.0) utils   no               GPL    
# 2 bar     1.0.0   R (>= 3.5.0) foo     no               GPL    

# Insert a line with a space after the ‘foo’ entry
lines = readLines(tmp)
writeLines(c(lines[1 : 6], ' ', lines[7 : 13]), tmp)

pkgcache::parse_packages(tmp)
# # A data frame: 2 × 6
#   Package Version Depends      Imports NeedsCompilation License
#   <chr>   <chr>   <chr>        <chr>   <chr>            <chr>  
# 1 bar     1.0.0   R (>= 3.5.0) foo     no               GPL    
# 2 NA      NA      NA           NA      NA               NA     

# But it works with read.dcf:
read.dcf(tmp)
#      Package Version Depends        Imports NeedsCompilation License
# [1,] "foo"   "1.0.0" "R (>= 3.5.0)" "utils" "no"             "GPL"  
# [2,] "bar"   "1.0.0" "R (>= 3.5.0)" "foo"   "no"             "GPL"  

klmr avatar Nov 04 '25 10:11 klmr

Seems to be fixed in dev pkgcache:

❯ readLines(tmp)
 [1] "Package: foo"          "Version: 1.0.0"        "Depends: R (>= 3.5.0)"
 [4] "Imports: utils"        "NeedsCompilation: no"  "License: GPL"
 [7] " "                     ""                      "Package: bar"
[10] "Version: 1.0.0"        "Depends: R (>= 3.5.0)" "Imports: foo"
[13] "NeedsCompilation: no"  "License: GPL"
❯ pkgcache::parse_packages(tmp)
# A data frame: 2 × 6
  Package Version Depends      Imports NeedsCompilation License
  <chr>   <chr>   <chr>        <chr>   <chr>            <chr>
1 foo     1.0.0   R (>= 3.5.0) utils   no               GPL
2 bar     1.0.0   R (>= 3.5.0) foo     no               GPL

gaborcsardi avatar Nov 04 '25 10:11 gaborcsardi

I can confirm that adding this line seem to fix the issue.

RUN Rscript -e 'install.packages("pak", repos = sprintf("https://r-lib.github.io/p/pak/%s/%s/%s/%s", "devel", .Platform$pkgType, R.Version()$os, R.Version()$arch))'

Does it build on top of dev pkgcache?

I am still confused why it doesn't break right away, but only on the second package dependencies installation.

idavydov avatar Nov 04 '25 11:11 idavydov

No, dev pak does not have the latest dev pkgcache. I just updated it, so it should work from tomorrow: https://github.com/r-lib/pak/commit/ab497a7ae5228963bfd2d87f95ccc488340e7729

gaborcsardi avatar Nov 04 '25 11:11 gaborcsardi

After building pak from ab497a7ae5228963bfd2d87f95ccc488340e7729 I wasn't able to reproduce the error in production. Thanks!

From my perspective this is resolved now and I can reopen it if the error reappears.

idavydov avatar Nov 04 '25 14:11 idavydov

Hey @gaborcsardi, is it possible to release that fix forpkgcache to CRAN? This bug is currently impacting our pipelines.

galachad avatar Nov 11 '25 17:11 galachad