9 Error messages | The tidyverse style guide (2024)

An error message should start with a general statement of the problem then give a concise description of what went wrong.Consistent use of punctuation and formatting makes errors easier to parse.

This guide assumes that you’re using cli::cli_abort().We are transitioning to use this function in the tidyverse because it:

Much of the advice in this guide still applies if you’re using stop(), but it will be be much more work to generate the message.

9.1 Problem statement

Every error message should start with a general statement of the problem.It should be concise, but informative (This is hard!).The problem statement should use sentence case and end with a full stop.

  • If the cause of the problem is clear (e.g.an incorrect type or size), use “must”:

    dplyr::nth(1:10, "x")#> Error:#> ! `n` must be a numeric vector, not a character vector.dplyr::nth(1:10, 1:2)#> Error:#> ! `n` must have length 1, not length 2.

    Do your best to tell the user both what is expected (“a numeric vector”) and what they actually provided (“a character vector”).

  • If you cannot state what was expected, use “can’t”:

    mtcars %>% pull(b)#> Error:#> ! Can't find column `b` in `.data`.as_vector(environment())#> Error:#> ! Can't coerce `.x` to a vector.purrr::modify_depth(list(list(x = 1)), 3, ~ . + 1)#> Error:#> ! Can't find specified `.depth` in `.x`.

9.2 Error location

Ideally the error message should mention the failing function call.

See https://rlang.r-lib.org/reference/topic-error-call.html for more about how to pass calls through error helpers.

9.3 Error details

After the problem statement, use a bulleted list to provide further information.Use cross bullets (x) to let the user know what the problem is, then use info bullets (i) to provide contextual information.These are easy to create with cli_abort():

Try to keep the sentences short and sweet:

# Goodvec_slice(letters, 100)#> ! Can't subset elements past the end.#> ℹ Location 100 doesn't exist.#> ℹ There are only 26 elements.# Badvec_slice(letters, 100)#> ! Must index an existing element.#> There are 26 elements and you've tried to subset element 100.

Do your best to reveal the location, name, and/or content of the troublesome component of the input.The goal is to make it as easy as possible for the user to find and fix the problem.

# Goodmap_int(1:5, ~ "x")#> Error:#> ! Each result must be a single integer.#> ✖ Result 1 is a character vector.# Badmap_int(1:5, ~ "x")#> Error:#> ! Each result must be a single integer

(It is often not easy to identify the exact problem; it may require passing around extra arguments so that error messages generated at a lower-level can know the original source. For frequently used functions, the effort is typically worth it.)

If the source of the error is unclear, avoid pointing the user in the wrong direction by giving an opinion about the source of the error:

# Goodpull(mtcars, b)#> Error:#> ! Can't find column `b` in `.data`.tibble(x = 1:2, y = 1:3, z = 1)#> Error:#> ! Tibble columns must have compatible sizes.#> • Size 2: Existing data.#> • Size 3: Column `y`.#> ℹ Only values of size one are recycled.# Bad: implies one argument at faultpull(mtcars, b)#> Error:#> ! Column `b` must exist in `.data`.pull(mtcars, b)#> Error:#> ! `.data` must contain column `b`.tibble(x = 1:2, y = 1:3, z = 1)#> Error:#> ! Column `x` must be length 1 or 3, not 2.

If there are multiple issues, or an inconsistency revealed across several arguments or items, prefer a bulleted list:

# Goodpurrr::reduce2(1:4, 1:2, `+`)#> Error:#> ! `.x` and `.y` must have compatible lengths:#> ✖ `.x` has length 4#> ✖ `.y` has length 2# Bad: harder to scanpurrr::reduce2(1:4, 1:2, `+`)#> Error:#> ! `.x` and `.y` must have compatible lengths: `.x` has length 4 and#> `.y` has length 2

If the list of issues might be long, make sure to truncate to only show the first few:

# Good#> Error: NAs found at 1,000,000 locations: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...

If you want to correctly pluralise the error message, consider using ngettext().See the notes in ?ngettext() for some challenges related to correct translation to other languages.

9.4 Hints

If the source of the error is clear and common, you may want to provide a hint as to how to fix it.The hint should be the last bullet, use an info bullet (i), and end in a question mark.

dplyr::filter(iris, Species = "setosa")#> Error:#> ! Filter specifications must be named.#> ℹ Did you mean `Species == "setosa"`?ggplot2::ggplot(ggplot2::aes())#> Error:#> ! Can't plot data with class "uneval".#> ℹ Did you accidentally provide the results of aes() to the `data` argument?mtcars |> ggplot() |> geom_point()#> Error in `validate_mapping()`:#> ! `mapping` must be created by `aes()`.#> ℹ Did you use %>% instead of +?

Hints are particularly important if the source of the error is far away from the root cause:

# Badmean[[1]]#> Error:#> ! object of type 'closure' is not subsettable# BETTERmean[[1]]#> Error:#> ! Can't subset a function.# BESTmean[[1]]#> Error:#> ! Can't subset a function.#> ℹ Have you forgotten to define a variable named `mean`?

Good hints are difficult to write because you want to avoid steering users in the wrong direction.Generally, we avoid writing a hint unless the problem is common, and you can easily find a common pattern of incorrect usage (e.g.by searching StackOverflow).

9.5 Punctuation

  • Errors should be written in sentence case, and should end in a full stop.Bullets should be formatted similarly; make sure to capitalise the first word (unless it’s an argument or column name).

  • Prefer the singular in problem statements:

    # Goodmap_int(1:2, ~ "a")#> Error:#> ! Each result must be coercible to a single integer.#> ✖ Result 1 is a character vector.# Badmap_int(1:2, ~ "a")#> Error:#> ! Results must be coercible to single integers.#> ✖ Result 1 is a character vector.
  • If you can detect multiple problems, list up to five.This allows the user to fix multiple problems in a single pass without being overwhelmed by many errors that may have the same source.

    # BETTERmap_int(1:10, ~ "a")#> Error:#> ! Each result must be coercible to a single integer.#> ✖ Result 1 is a character vector#> ✖ Result 2 is a character vector#> ✖ Result 3 is a character vector#> ✖ Result 4 is a character vector#> ✖ Result 5 is a character vector#> ... and 5 more problems
  • Pick a natural connector between problem statement and error location: this may be “, not”, “;”, or “:” depending on the context.

  • Surround the names of arguments in backticks, e.g.`x`.Use “column” to disambiguate columns and arguments: Column `x`.Avoid “variable”, because it is ambiguous.

  • Ideally, each component of the error message should be less than 80 characters wide.Do not add manual line breaks to long error messages; they will not look correct if the console is narrower (or much wider) than expected.Instead, use bullets to break up the error into shorter logical components.In case you do need longer sentences, let cli perform paragraph wrapping automatically.It inserts newlines automatically depending on the width of the console.

9.6 Before and after

More examples gathered from around the tidyverse.

dplyr::filter(mtcars, cyl)#> BEFORE:#> ! Argument 2 filter condition does not evaluate to a logical vector.#> AFTER:#> ! Each argument must be a logical vector.#> * Argument 2 (`cyl`) is an integer vector.tibble::tribble("x", "y")#> BEFORE: ! Expected at least one column name; e.g. `~name`#> AFTER: ! Must supply at least one column name, e.g. `~name`.ggplot2::ggplot(data = diamonds) + ggplot2::geom_line(ggplot2::aes(x = cut))#> BEFORE: ! geom_line requires the following missing aesthetics: y#> AFTER: ! `geom_line()` must have the following aesthetics: `y`.dplyr::rename(mtcars, cyl = xxx)#> BEFORE: ! `xxx` contains unknown variables#> AFTER: ! Can't find column `xxx` in `.data`.dplyr::arrange(mtcars, xxx)#> BEFORE: ! Evaluation error: object 'xxx' not found.#> AFTER: ! Can't find column `xxx` in `.data`.

9.7 Localisation

It is encouraged to be as informative as possible, but each sentence should be very simple to make localisation and translation possible.A Localization Horror Story: It Could Happen To You is a Good summary of the challenges of localising error messages.You might not support localised messages right now but you should make it as easy as possible to do it in the future.

9 Error messages | The tidyverse style guide (2024)
Top Articles
What are Collateralized Debt Obligations (CDOs), and How Does it Work? - Wint Wealth
9 Ways | How to Recover Deleted History on Safari (iPhone/Mac)
Ups Customer Center Locations
Blorg Body Pillow
Moon Stone Pokemon Heart Gold
Valley Fair Tickets Costco
Erika Kullberg Wikipedia
How Many Cc's Is A 96 Cubic Inch Engine
Craigslist Free Stuff Appleton Wisconsin
When is streaming illegal? What you need to know about pirated content
United Dual Complete Providers
Housing Intranet Unt
Facebook Marketplace Charlottesville
Evangeline Downs Racetrack Entries
FAQ: Pressure-Treated Wood
Radio Aleluya Dialogo Pastoral
Hartland Liquidation Oconomowoc
4156303136
Gmail Psu
Vcuapi
Ostateillustrated Com Message Boards
"Une héroïne" : les funérailles de Rebecca Cheptegei, athlète olympique immolée par son compagnon | TF1 INFO
List of all the Castle's Secret Stars - Super Mario 64 Guide - IGN
Allentown Craigslist Heavy Equipment
Never Give Up Quotes to Keep You Going
Gran Turismo Showtimes Near Marcus Renaissance Cinema
R&S Auto Lockridge Iowa
Restored Republic June 16 2023
Craigslist Dubuque Iowa Pets
Tokyo Spa Memphis Reviews
Inter Miami Vs Fc Dallas Total Sportek
Amazing Lash Bay Colony
Half Inning In Which The Home Team Bats Crossword
What Time Is First Light Tomorrow Morning
Viewfinder Mangabuddy
Chatropolis Call Me
NHL training camps open with Swayman's status with the Bruins among the many questions
Linda Sublette Actress
Restored Republic June 6 2023
Pulitzer And Tony Winning Play About A Mathematical Genius Crossword
Big Reactors Best Coolant
Portal Pacjenta LUX MED
Suntory Yamazaki 18 Jahre | Whisky.de » Zum Online-Shop
Aznchikz
The Quiet Girl Showtimes Near Landmark Plaza Frontenac
Automatic Vehicle Accident Detection and Messageing System – IJERT
Washington Craigslist Housing
Julies Freebies Instant Win
Where and How to Watch Sound of Freedom | Angel Studios
Ark Silica Pearls Gfi
Sunset On November 5 2023
Latest Posts
Article information

Author: Eusebia Nader

Last Updated:

Views: 6695

Rating: 5 / 5 (60 voted)

Reviews: 91% of readers found this page helpful

Author information

Name: Eusebia Nader

Birthday: 1994-11-11

Address: Apt. 721 977 Ebert Meadows, Jereville, GA 73618-6603

Phone: +2316203969400

Job: International Farming Consultant

Hobby: Reading, Photography, Shooting, Singing, Magic, Kayaking, Mushroom hunting

Introduction: My name is Eusebia Nader, I am a encouraging, brainy, lively, nice, famous, healthy, clever person who loves writing and wants to share my knowledge and understanding with you.