S7 Replacement Methods and the R CMD Check Crash

r
s7
packages
Author

James Balamuta

Published

February 8, 2026

If you’re using S7 in an R package and registering methods for replacement operators ($<-, [[<-, [<-), you’ve probably hit this:

W  checking replacement functions ...
   Error in get(f, envir = code_env) : invalid first argument
   The argument of a replacement function which corresponds to the right
   hand side must be named 'value'.

Your code is fine. This is a bug in R CMD check.

What’s going on

When S7 registers a replacement method, it stores a function object in the S3 methods table. R CMD check’s checkReplaceFuns() expects string names there. It coerces the function to "", calls get(""), and crashes. The “must be named value” message is boilerplate that prints after the crash. It never actually inspected your function signature.

Is there a fix?

Yes, Martin Maechler fixed this in R-devel across three commits:

  • https://github.com/r-devel/r-svn/commit/65aeb9d18476af311f7a4f9e36740e57181cffb4 (svn 88398, Jul 10 2025) — initial fix
  • https://github.com/r-devel/r-svn/commit/5d5cd454fb6d38bb49660a7afcda08310947ab56 (svn 88404, Jul 11 2025) — amendment
  • https://github.com/r-devel/r-svn/commit/4fcf661db9360a7c6162f9cb07118ba940763f31 (svn 88418, Jul 16 2025) — reporting improvement

tools::checkReplaceFuns() now deals better with replacement methods not available as regular functions in the namespace.

It will ship in R 4.6. It is not in R 4.5.x or earlier.

The workaround

Move your replacement method registrations into .onLoad(). The check only scans top-level source assignments such as methods registered at load time bypass it and dispatch identically at runtime.

Read-only methods ($, [[, names) are unaffected and can stay at the top level.

# R/methods.R
S7::method(`$`, MyClass)   <- function(x, name) { S7::prop(x, name) }
S7::method(`[[`, MyClass)  <- function(x, i, ...) { S7::prop(x, i) }
S7::method(names, MyClass) <- function(x) { names(S7::props(x)) }

# Implementations for replacement ops (registered in zzz.R)
.my_dollar_set   <- function(x, name, value) { S7::prop(x, name) <- value; x }
.my_bracket2_set <- function(x, i, ..., value) { S7::prop(x, i) <- value; x }

# R/zzz.R
.onLoad <- function(libname, pkgname) {
  S7::methods_register()
  S7::method(`$<-`, MyClass)  <- .my_dollar_set
  S7::method(`[[<-`, MyClass) <- .my_bracket2_set
}

Related

  • https://github.com/RConsortium/S7/issues/569 — Hadley’s report from stringr
  • https://github.com/RConsortium/S7/issues/549 — original report, closed when R-devel fix landed
  • https://github.com/RConsortium/S7/issues/562 — .onLoad() workaround discussed
  • https://github.com/r-devel/r-svn/commit/65aeb9d18476af311f7a4f9e36740e57181cffb4 — the actual commit in tools::checkReplaceFuns()