rguides

stop

stop(..., call. = TRUE, domain = NULL)

stop() is the primary way to signal an error in R. It halts execution immediately, prints an error message, and transfers control to the error handler. Every serious R package uses it internally, and you will reach for it whenever your code needs to fail fast on invalid input or impossible conditions.

Parameters

ParameterTypeDefaultDescription
...objects,One or more objects coerced to character and pasted together. Can also be a single condition object.
call.logicalTRUEIf TRUE, the call that triggered stop() appears in the error message. Set to FALSE for cleaner output.
domainNULL or NANULLMessage translation domain. Use NA to suppress translation.

Return value

stop() never returns. It halts execution and transfers control to the error handler.

Basic error signaling

The simplest use passes a character message:

validate_age <- function(age) {
  if (age < 0) {
    stop("Age cannot be negative")
  }
  if (age > 150) {
    stop("Age value is implausible")
  }
  age
}

validate_age(-5)
# Error: Age cannot be negative

stop() accepts multiple arguments and pastes them without any separator, so include spaces explicitly. This is a common stumbling block: stop("value is", x) produces “value is42” instead of “value is 42”. The arguments are coerced to character individually and concatenated, which is convenient for building error messages from variables and string fragments in one call.

x <- NULL
stop("Object is", if (is.null(x)) " NULL" else " valid")
# Error: Object is NULL

The multi-argument paste behaviour also means you must include trailing spaces in each string fragment. stop("Error at index", i, "value", v) pastes everything without gaps. For cleaner error messages, use sprintf() or paste0() to build the message string beforehand, then pass a single argument to stop(). This avoids confusion and makes the error text predictable.

Controlling call display

The call. parameter determines whether the surrounding function call appears in the error output. Default is TRUE, which includes the full call:

tst_with_call <- function(x) {
  stop("an error occurred", call. = TRUE)
}

tst_without_call <- function(x) {
  stop("an error occurred", call. = FALSE)
}

tst_with_call(NULL)
# Error in tst_with_call(NULL) : an error occurred

tst_without_call(NULL)
# Error: an error occurred

In package code, call. = FALSE often produces less noisy messages. The choice depends on whether the caller context helps the user debug the problem.

Using condition objects

You can pass a condition object through ... instead of a character string. The condition must have class "error" or inherit from it:

my_error <- function(message) {
  structure(
    list(message = message),
    class = c("my_error", "error", "condition")
  )
}

tryCatch(
  stop(my_error("custom condition object")),
  error = function(e) {
    cat("Caught: ", e$message, "\n")
  }
)
# Caught:  custom condition object

This pattern is the basis for custom error classes in R packages. By defining a condition class that inherits from "error", you can create domain-specific errors that tryCatch() dispatches to the appropriate handler based on class inheritance — class(e) %in% c("my_error", "error", "condition") means the handler matches on the custom class as well as the generic error class.

Using stop() with tryCatch()

stop() creates a condition of class error (specifically, an object inheriting from "simpleError"), which tryCatch() handles:

divide <- function(a, b) {
  if (b == 0) stop("Division by zero")
  a / b
}

result <- tryCatch(
  divide(10, 0),
  error = function(e) {
    message("Error caught: ", e$message)
    NA
  }
)
# Error: Division by zero
# Error caught: Division by zero
# [1] NA

The error message prints before tryCatch() catches it, because R prints the message before invoking the default handler. To suppress the printed message, set options(show.error.messages" = FALSE) before the call.

Common mistakes

Expecting a return value. stop() never returns, code after stop() in the same block is never executed. If you wrap stop() in tryCatch(), the tryCatch() block returns whatever you specify in the error handler.

Forgetting separators in .... All arguments paste directly without spaces:

# WRONG
stop("value is", x)     # no space before x

# RIGHT
stop("value is ", x)    # explicit space

Using call. = TRUE in deep recursion. The call stack included in the error message grows with recursion depth, making the output harder to read.

stop() raises an error and halts execution. The error message can be caught with tryCatch(expr, error = function(e) ...). Pass call. = FALSE to omit the call stack from the error message, which is standard practice in package code for cleaner user-facing errors.

See also