I think it makes more sense to specify what the argument should be than what it should not be.
With my tool of choice, for example, if I want a character vector of length one with a nonempty string...
library(vetr)
NZCHR = vet_token(nzchar(.), "%sshould not be an empty string, but it is.")
GOODCHR = quote(CHR.1 && NZCHR)
f = function(x){
vetr(GOODCHR)
cat(x, "\tOh and Hello World!\n")
}
Usage
> f("Huzzah")
Huzzah Oh and Hello World!
> f(c("Huzzah", "Yahoo"))
Error in f(x = c("Huzzah", "Yahoo")) :
For argument `x`, `length(c("Huzzah", "Yahoo"))` should be 1 (is 2)
> f(character(0))
Error in f(x = character(0)) :
For argument `x`, `length(character(0))` should be 1 (is 0)
> f("")
Error in f(x = "") :
For argument `x`, `""` should not be an empty string, but it is.
> f(NULL)
Error in f(x = NULL) :
For argument `x`, `NULL` should be type "character" (is "NULL")
> f(NA)
Error in f(x = NA) :
For argument `x`, `NA` should be type "character" (is "logical")
> f(NaN)
Error in f(x = NaN) :
For argument `x`, `NaN` should be type "character" (is "double")
There are many other "assertion" packages similar to vetr noted on its home page. Regarding 'verse compatibility, with vetr it's taken into account in providing a tev function that goes well with pipes; and there are no dependencies in the version now on CRAN.