From 285981cbcb6508ab973af289209e8ecae7cb7697 Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Sat, 12 Sep 2026 08:32:00 -0400 Subject: [PATCH 1/2] Error on empty column names --- r/R/dplyr-eval.R | 9 +++++++++ r/tests/testthat/test-dplyr-eval.R | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/r/R/dplyr-eval.R b/r/R/dplyr-eval.R index 1282f171878d..5ed95c7646d7 100644 --- a/r/R/dplyr-eval.R +++ b/r/R/dplyr-eval.R @@ -252,6 +252,15 @@ abandon_ship <- function(err, env) { arrow_mask <- function(.data) { f_env <- new_environment(.cache$functions) + # Empty column names can't be bound into an environment (GH-40303). + # Like dplyr, refuse to transform such data rather than repairing names. + if (!all(nzchar(names(.data$selected_columns)))) { + abort(c( + "Can't transform data with empty (`\"\"`) column names.", + i = "Rename or drop the unnamed columns first, e.g. with `rename()` or `select()`." + )) + } + # Assign the schema to the expressions schema <- .data$.data$schema walk(.data$selected_columns, ~ (.$schema <- schema)) diff --git a/r/tests/testthat/test-dplyr-eval.R b/r/tests/testthat/test-dplyr-eval.R index 0b0b9f98f432..50ab3a6c3834 100644 --- a/r/tests/testthat/test-dplyr-eval.R +++ b/r/tests/testthat/test-dplyr-eval.R @@ -59,3 +59,28 @@ test_that("try_arrow_dplyr/abandon_ship adds the right message about collect()", expect_snapshot(tester(ds, i), error = TRUE) } }) + +test_that("dplyr verbs error clearly on empty column names", { + # GH-40303 + tbl <- example_data + names(tbl)[1] <- "" + + # dplyr also refuses these ("Can't transform a data frame with `NA` or + # `""` names."), but our wording differs since the input isn't a data frame + tab <- arrow_table(tbl) + msg <- "Can't transform data with empty" + expect_error(tab |> mutate(z = dbl + 1), msg) + expect_error(tab |> filter(dbl > 4), msg) + expect_error(tab |> arrange(dbl), msg) + expect_error(tab |> group_by(dbl), msg) + + # select() and rename() still work as an escape hatch, as in dplyr + compare_dplyr_binding( + .input |> select(-1) |> mutate(z = dbl + 1) |> collect(), + tbl + ) + compare_dplyr_binding( + .input |> rename(int = 1) |> mutate(z = dbl + 1) |> collect(), + tbl + ) +}) From 92ae85b891ac0fba7fcafc57ceaec02c16463ccc Mon Sep 17 00:00:00 2001 From: Nic Crane Date: Wed, 16 Sep 2026 11:30:44 -0500 Subject: [PATCH 2/2] Add test for empty column names in dplyr verbs Add test for dplyr verbs handling empty column names. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- r/tests/testthat/test-dplyr-eval.R | 1 + 1 file changed, 1 insertion(+) diff --git a/r/tests/testthat/test-dplyr-eval.R b/r/tests/testthat/test-dplyr-eval.R index 50ab3a6c3834..78bd84eb6d21 100644 --- a/r/tests/testthat/test-dplyr-eval.R +++ b/r/tests/testthat/test-dplyr-eval.R @@ -61,6 +61,7 @@ test_that("try_arrow_dplyr/abandon_ship adds the right message about collect()", }) test_that("dplyr verbs error clearly on empty column names", { + skip_if_not_available("acero") # GH-40303 tbl <- example_data names(tbl)[1] <- ""