From 7967b1da0a38a188254a294401b708654fcc87a2 Mon Sep 17 00:00:00 2001 From: Utkarsh Date: Tue, 7 Apr 2026 16:10:59 +0530 Subject: [PATCH 1/2] validate empty list and zero-row matrix inputs in nuts_params.list() --- NEWS.md | 1 + R/bayesplot-extractors.R | 8 ++++++++ tests/testthat/test-extractors.R | 13 +++++++++++++ 3 files changed, 22 insertions(+) diff --git a/NEWS.md b/NEWS.md index c8f7d131f..99ec1f42e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,6 @@ # bayesplot (development version) +* Validate empty list and zero-row matrix inputs in `nuts_params.list()`. * Replace `apply()` with `storage.mode()` for integer-to-numeric matrix conversion in `validate_predictions()`. * Fixed `is_chain_list()` to correctly reject empty lists instead of silently returning `TRUE`. * Added unit tests for `mcmc_areas_ridges_data()`, `mcmc_parcoord_data()`, and `mcmc_trace_data()`. diff --git a/R/bayesplot-extractors.R b/R/bayesplot-extractors.R index 19c6df882..d928224bc 100644 --- a/R/bayesplot-extractors.R +++ b/R/bayesplot-extractors.R @@ -145,10 +145,18 @@ nuts_params.stanreg <- #' @export #' @method nuts_params list nuts_params.list <- function(object, pars = NULL, ...) { + if (length(object) == 0) { + abort("'object' must be a non-empty list.") + } + if (!all(sapply(object, is.matrix))) { abort("All list elements should be matrices.") } + if (nrow(object[[1]]) == 0) { + abort("All matrices in the list must have at least one row.") + } + dd <- lapply(object, dim) if (length(unique(dd)) != 1) { abort("All matrices in the list must have the same dimensions.") diff --git a/tests/testthat/test-extractors.R b/tests/testthat/test-extractors.R index 53e9862cc..9f218e3f5 100644 --- a/tests/testthat/test-extractors.R +++ b/tests/testthat/test-extractors.R @@ -9,6 +9,8 @@ x <- list(cbind(a = 1:3, b = rnorm(3)), cbind(a = 1:3, b = rnorm(3))) # nuts_params and log_posterior methods ----------------------------------- test_that("nuts_params.list throws errors", { + expect_error(nuts_params.list(list()), "non-empty list") + x[[3]] <- c(a = 1:3, b = rnorm(3)) expect_error(nuts_params.list(x), "list elements should be matrices") @@ -17,6 +19,17 @@ test_that("nuts_params.list throws errors", { x[[3]] <- cbind(a = 1:4, b = rnorm(4)) expect_error(nuts_params.list(x), "same dimensions") + + zero_row <- list(cbind(a = numeric(0), b = numeric(0))) + expect_error(nuts_params.list(zero_row), "at least one row") +}) + +test_that("nuts_params.list works with single-chain list", { + single <- list(cbind(a = 1:3, b = rnorm(3))) + np <- nuts_params.list(single) + expect_identical(colnames(np), c("Chain", "Iteration", "Parameter", "Value")) + expect_true(all(np$Chain == 1L)) + expect_equal(nrow(np), 6L) }) test_that("nuts_params.list parameter selection ok", { From 62389776acc53ce5aa16b40083ad7a08fa6b7638 Mon Sep 17 00:00:00 2001 From: Utkarsh Date: Tue, 7 Apr 2026 16:19:51 +0530 Subject: [PATCH 2/2] check zero-row matrices across all list elements in nuts_params.list() --- R/bayesplot-extractors.R | 2 +- tests/testthat/test-extractors.R | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/R/bayesplot-extractors.R b/R/bayesplot-extractors.R index d928224bc..c17bf45b4 100644 --- a/R/bayesplot-extractors.R +++ b/R/bayesplot-extractors.R @@ -153,7 +153,7 @@ nuts_params.list <- function(object, pars = NULL, ...) { abort("All list elements should be matrices.") } - if (nrow(object[[1]]) == 0) { + if (any(vapply(object, nrow, integer(1)) == 0)) { abort("All matrices in the list must have at least one row.") } diff --git a/tests/testthat/test-extractors.R b/tests/testthat/test-extractors.R index 9f218e3f5..74b9731a8 100644 --- a/tests/testthat/test-extractors.R +++ b/tests/testthat/test-extractors.R @@ -22,6 +22,9 @@ test_that("nuts_params.list throws errors", { zero_row <- list(cbind(a = numeric(0), b = numeric(0))) expect_error(nuts_params.list(zero_row), "at least one row") + + zero_row_nonfirst <- list(cbind(a = 1:3, b = rnorm(3)), cbind(a = numeric(0), b = numeric(0))) + expect_error(nuts_params.list(zero_row_nonfirst), "at least one row") }) test_that("nuts_params.list works with single-chain list", {