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
| Parameter | Type | Default | Description |
|---|---|---|---|
... | objects | — | One or more objects coerced to character and pasted together. Can also be a single condition object. |
call. | logical | TRUE | If TRUE, the call that triggered stop() appears in the error message. Set to FALSE for cleaner output. |
domain | NULL or NA | NULL | Message 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:
x <- NULL
stop("Object is", if (is.null(x)) " NULL" else " valid")
# Error: Object is NULL
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.
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.
See Also
tryCatch()— catch and handle errors with error handlerswithCallingHandlers()— establish local handlers with finer control- Error handling in R — patterns and best practices for careful error management