Every checktor check rests on a source, and the source sets its severity. This page maps each check to its authority, links the exact section wherever one exists, and gives the severity that authority earns. For the full argument and the exemptions, read the check’s help page, such as ?lab_option_changes.
Severity tells you what kind of authority stands behind a check.
policy is a rule CRAN enforces. Breaking one can get a package rejected, and a policy finding counts against overall health. Most of these rules are written in the CRAN Repository Policy or Writing R Extensions, the two documents CRAN treats as binding. Some mirror a CRAN incoming check, one of the NOTEs that R CMD check --as-cran raises against a submission. For a few long-standing reviewer requirements that neither manual states, the CRAN Cookbook is the written record. Restoring options(), par() and the working directory is the clearest case. It is among the most common reasons a package is sent back, and neither manual mentions it.robustness is a real defect that CRAN will still accept, such as a detectCores() that can return NA. It counts toward overall health too, because the defect is real whether or not CRAN objects to it.opinion is a convention that experienced maintainers and reviewers tend to ask for, with nothing enforcing it. checktor reports it but leaves it out of overall health, which by default counts policy and robustness alone.
The Source column in each table below gives the authority. Many conventions are written down in the CRAN Cookbook, the R Contributor guide to the problems that get packages sent back. Where it has a recipe, the column links to it. For checks with no citable source, the column reads “No formal rule”, “No rule” or “Convention only”.
Most checks run every time. Some depend on the machine. When one of those cannot run, checktor() reports it as skipped rather than passed, so good overall health never rests on a check that did not happen. The skipped column of tidy() marks it, and metadata$skipped_checks lists it. Checks are also skipped when their input cannot be read. If R cannot read DESCRIPTION, every check that reads its fields is skipped, and description_file reports the problem as a policy finding. If Authors@R cannot be read, identifier_format is skipped.
Others run only when you call them. Nothing asked for them, so they are not skipped, and metadata$on_request_checks lists them so you can find them.
| Check | Runs | Why |
|---|---|---|
url_liveness |
at the console | It fetches every URL, so it stays off in scripts and under R CMD check, where the network would decide the result. options(checktor.url_check = TRUE) runs it everywhere. |
spelling |
with a backend | It needs aspell or hunspell installed. options(checktor.spelling = FALSE) turns it off and reports it as skipped. options(checktor.disable = "spelling") or Config/checktor/disable: spelling leaves it out of the run entirely. |
cran_comments_file |
when you call it | cran-comments.md belongs to the submission workflow rather than to the package. |
title_starts_with_article |
when you call it | No authority supports it, so it stays available without joining the run. |
description_function_quotes |
when you call it | No authority supports it either, and Writing R Extensions points the other way. |
cph_role |
when you call it | ?person says authors who are natural persons hold copyright by default, so most packages need no cph role. |
format_names |
when you call it | CRAN accepts JSON, HTML, SQL and the other format names written bare, so quoting them is a matter of style. |
Every other check runs always, and new checks join the run unless their row in the registry says otherwise. No check goes missing because someone forgot to switch it on.
| Check | Severity | Source |
|---|---|---|
seed_setting |
policy |
CRAN Policy: a package “should not modify the global environment”, and set.seed() writes .Random.seed there. Recipe: Setting a Specific Seed. |
print_cat_usage |
policy |
Cookbook: Using print()/cat(): diagnostic output belongs in message() or warning(), which a user can suppress. Reviewers require it, though neither manual states it. |
option_changes |
policy |
Cookbook: Change of Options, Graphical Parameters and Working Directory: restore anything a function changes, with on.exit(). Neither manual states this, but it is among the most common reasons a package is sent back. |
warn_option |
policy |
Cookbook: Setting options(warn = -1): the same requirement, for the warning level. |
home_writing |
policy |
CRAN Policy: “Packages should not write in the user’s home filespace … nor anywhere else on the file system apart from the R session’s temporary directory”. Recipe: Writing Files and Directories to the Home Filespace. |
globalenv_mod |
policy |
CRAN Policy: “Packages should not modify the global environment (user’s workspace).” Recipe: Writing to the .GlobalEnv. |
installed_packages |
policy |
CRAN Policy: a package must not install other packages when it runs. Recipe: Calling installed.packages(). |
software_install |
policy |
CRAN Policy: a package must not download and install external software at load or run time. Recipe: Installing Software. |
core_usage |
policy |
CRAN Policy: “If running a package uses multiple threads/cores it must never use more than two simultaneously”. Recipe: Using more than 2 Cores. |
sys_setenv |
policy |
No clause mentions environment variables, but they are session state in the same way options() are, so the same restore-on-exit requirement applies. See Cookbook: Change of Options, Graphical Parameters and Working Directory. |
tf_usage |
robustness |
No binding rule, but a documented one in Cookbook: T/F Instead of TRUE/FALSE. T and F are ordinary variables (see ?logical) that code can rebind, so they make unsafe stand-ins. |
library_in_pkg |
robustness |
WRE: Package Dependencies: package code should reach dependencies through Imports and ::, not attach them with library(). |
detect_cores_robustness |
robustness |
No formal rule. ?detectCores states it returns “NA if the answer is unknown”, and the arithmetic that usually follows then crashes. |
hardcoded_credentials |
robustness |
No formal rule. Tokens and keys committed to a package are public the moment it reaches CRAN, and must be revoked. |
internal_ns |
robustness |
CRAN asks you to omit one colon, since ::: reaches an object whose author may change it. R CMD check reports it too, under dependencies in R code. |
temp_cleanup |
opinion |
Cookbook: Leaving Files in the Temporary Directory. R removes tempdir() when the session ends, so a temporary file nobody unlink()ed breaks no rule. That keeps this check advisory. |
| Check | Severity | Source |
|---|---|---|
description_file |
policy |
WRE: The DESCRIPTION file: “Fields start with an ASCII name immediately followed by a colon” and “Continuation lines … start with a space or tab”. R CMD build and R CMD INSTALL stop on a file that breaks this, or that a blank line splits in two. |
description_fields |
policy |
CRAN incoming check: it NOTEs “Unknown, possibly misspelled, fields in DESCRIPTION”, allowing Config/ and a few other prefixes. Remotes is the usual one. CRAN Policy wants strong dependencies “available from CRAN or the Bioconductor software repository”. |
description_placeholders |
policy |
CRAN incoming check: it NOTEs “DESCRIPTION fields with placeholder content”, the Title, Description, Author or Maintainer a usethis or package.skeleton() template wrote. |
software_names |
policy |
WRE: The DESCRIPTION file: “Refer to other packages and external software in single quotes”. Recipe: Formatting Software Names. |
language_names |
policy |
WRE: The DESCRIPTION file: the same rule, for programming languages and statistical software such as Python, Java, MATLAB and SAS. Recipe: Formatting Software Names. |
description_quoted_quotes |
policy |
WRE: The DESCRIPTION file: double quotes are for book titles and similar, and software names take single quotes. The format names format_names covers are left out, since CRAN accepts them bare. Recipe: Formatting Software Names. |
license |
policy |
CRAN Policy: an invalid or unrecognized License field is a rejection. Recipe: LICENSE files. |
license_file_unneeded |
policy |
Cookbook: LICENSE files: CRAN does “not need” + file LICENSE “and the file as these are part of R”, unless the file adds attribution requirements or restrictions. R CMD check NOTEs the pointer on a license that takes no extension, and the incoming check NOTEs it on one that does, such as GPL-3. |
authors |
policy |
CRAN Policy: a placeholder or malformed Authors@R, including a missing maintainer, is a rejection. Recipe: Using Authors@R. |
title_case |
policy |
WRE: The DESCRIPTION file: the Title “should use title case”. The --as-cran incoming check flags one that does not. Recipe: Title Case. |
title_package_name |
policy |
WRE: The DESCRIPTION file: “Do not repeat the package name: it is often used prefixed by the name.” The incoming check NOTEs a Title that is the name or starts with it. Only the name alone and name: are flagged, since CRAN routinely accepts a name that is an ordinary word, as in “Survival Analysis”. |
date_format |
policy |
WRE: The DESCRIPTION file: “the ‘yyyy-mm-dd’ format of the ISO 8601 standard is strongly recommended”. The incoming check also flags a stale or future date. |
version_format |
policy |
WRE: The DESCRIPTION file: a Version is “a sequence of at least two … non-negative integers”. The incoming check flags a leading zero or an implausible value. |
encoding_utf8 |
policy |
WRE: The DESCRIPTION file: a non-ASCII DESCRIPTION “should contain an ‘Encoding’ field”. The incoming check NOTEs any value other than UTF-8 as deprecated, latin1 and latin2 included. |
description_starts_with |
policy |
WRE: The DESCRIPTION file: “It is good practice not to start with the package name, ‘This package’ or similar”. The incoming check flags it. |
references |
policy |
CRAN incoming check: it NOTEs a URL outside <...>, a DOI not written <doi:prefix/suffix> or given as a publisher link, and an arXiv id where the submission checklist asks for the arXiv DOI <doi:10.48550/arXiv.ID>. Recipe: References. |
identifier_format |
policy |
CRAN incoming check: it NOTEs a malformed ORCID or ROR identifier in Authors@R. |
license_year |
robustness |
No binding rule. Leaving <YEAR> or <COPYRIGHT HOLDER> in the LICENSE template puts a placeholder where the copyright notice belongs. Recipe: LICENSE files. |
spelling |
opinion |
CRAN incoming check (aspell), but it needs a spell-check backend and is noisy, so checktor keeps it advisory. |
acronyms |
opinion |
Cookbook: Explaining Acronyms. Reviewers ask for an acronym to be spelled out once, but nothing enforces it. |
cph_role |
opinion |
?person: cph is for copyright holders, and authors who are natural persons hold copyright by default without it. CRAN Policy asks only that ownership be clear, which a Copyright field also achieves. Runs on request. |
format_names |
opinion |
No rule. WRE: The DESCRIPTION file asks for quotes around software, and JSON, HTML, XML, CSS, YAML, TOML, Markdown, LaTeX, TeX and SQL are formats. C++, Fortran and Tcl are written either way. In a census of CRAN in September 2026, packages accepted at new-package review in the previous 18 months wrote these bare 62% of the time, against 28% for the names language_names checks. Runs on request. |
description_length |
opinion |
Cookbook: Description Length. Reviewers find a one-line Description thin and ask for more. |
title_length |
opinion |
WRE: The DESCRIPTION file: “Some package listings may truncate the title to 65 characters”. That is a display width rather than a limit, so a Title that fills it exactly still shows in full, and nothing rejects a longer one. |
title_redundant_phrases |
opinion |
Convention only. Phrases like “R package to” are redundant in a Title. |
title_starts_with_article |
opinion |
No rule. The real CRAN rule, which description_starts_with enforces, concerns the opening of the Description. Kept callable but off by default. |
description_function_quotes |
opinion |
No rule, and Writing R Extensions points the other way. Kept callable but off by default. |
| Check | Severity | Source |
|---|---|---|
suggested_in_examples |
policy |
WRE: Suggested packages: a package from Suggests used in an example must be guarded so the example still runs without it. |
rd_bibliography |
policy |
WRE: Bibliographic citations and references: R 4.6’s \bibcitet{}, \bibcitep{} and \bibshow{} read the package bibliography. R CMD check warns “Could not find bibentries for the following keys” and notes “Bibentries cited but not shown”, and --as-cran notes a REFERENCES file at the top level as non-standard. |
roxygen_usage |
robustness |
No binding rule. Functions tagged @export that never reached NAMESPACE are not exported. Recipe: Repeated Rejections of Issues in Manuals If Using roxygen2. |
unexported_example_ns |
robustness |
No formal rule. Examples that reach for an unexported object error when they run. |
rd_bibliography_files |
robustness |
WRE: Bibliographic citations and references keeps the bibliography as inst/REFERENCES.R or inst/REFERENCES.bib, which “needs bibtex to be installed”. Nothing checks either. Without bibtex in Suggests, a .bib fails a build that installs only what is declared, and one outside inst/ is never installed for another package’s pkg::key. |
value_tags |
opinion |
WRE: Documenting functions describes \value{}, and Cookbook: Missing -tags in .Rd-files is the recipe reviewers cite, but R CMD check does not require it. |
example_structure |
opinion |
Cookbook: Structuring of Examples. \dontrun{} should wrap only code that cannot run inside a check. |
donttest_vs_dontrun |
opinion |
Cookbook: Structuring of Examples: \donttest{} is the wrapper for examples that merely run long, where many reach for \dontrun{} instead. |
missing_examples |
opinion |
Cookbook: Structuring of Examples. Exported functions are expected to carry an \examples{} block. |
commented_examples |
opinion |
Convention only. Commenting out a whole \examples{} block leaves it demonstrating nothing. |
These checks cover the code outside R/ that CRAN reads, where several of the most common rejections land. Maintainers have received each rule below, verbatim, in a reply from CRAN.
| Check | Severity | Source |
|---|---|---|
example_interactive |
policy |
Cookbook: Structuring of Examples: a function that only runs interactively belongs in if (interactive()), so a reader sees it is not for a script, rather than in \dontrun{}. In \donttest{} it does more harm, because R CMD check --as-cran runs that code, where a prompt errors and an app waits for input. |
example_installs |
policy |
Cookbook: Installing Software: do not install packages from a function, an example or a vignette. |
example_writes |
policy |
Cookbook: Writing Files and Directories to the Home Filespace: an example, vignette or test may write only to tempdir(). |
example_state |
policy |
Cookbook: Change of Options, Graphical Parameters and Working Directory: restore options(), par() and the working directory changed in an example, vignette or demo. |
example_internal_ns |
policy |
CRAN asks you to omit one colon, since ::: reaches an object whose behavior the author may change. |
example_tf_usage |
robustness |
Cookbook: T/F Instead of TRUE/FALSE: T and F “should not be used as variable names in your code, examples, tests or vignettes”. The same rule as tf_usage, applied to examples, vignettes and demos. |
example_unparseable |
robustness |
Reviewers send this rejection verbatim: “Unexecutable code in man/…Rd”. WRE: Documenting functions lets \dontrun{} text be something other than R, but reviewers run examples with it included, and R CMD check never parses it, so a missing bracket or a <your key> placeholder there goes unseen. |
| Check | Severity | Source |
|---|---|---|
code_exercised |
policy |
CRAN incoming check: --as-cran WARNs “No examples, no tests, no vignettes” for a package that exports code and includes none of the three. CRAN Policy asks that “the checks that are left do exercise all the features of the package”. |
citation_file |
policy |
CRAN incoming check: --as-cran NOTEs an inst/CITATION that calls the old-style citEntry() or personList(), and lists calls to packageDescription(), library() and require(). WRE: CITATION files: “It is desirable (and essential for CRAN) that the CITATION file does not contain calls to functions such as packageDescription which assume the package is installed”. |
package_size |
policy |
CRAN Policy: CRAN limits the size of the built tarball. Recipe: Package Size, which gives the practical figures. |
url_liveness |
robustness |
CRAN incoming check: --as-cran fetches URLs and NOTEs 404s and redirects. It runs at the console and stays off in scripts and checks, where the network would decide the result. |
readme_links |
robustness |
No formal rule. Relative README links whose targets are excluded from the tarball break on the package page. |
urls |
opinion |
Convention only. Preferring https:// is good advice, but CRAN’s NOTE is about broken URLs rather than the scheme. |
news_file |
opinion |
Convention only. NEWS files are expected but not required. |
cran_comments_file |
opinion |
Convention only. cran-comments.md belongs to the submission workflow rather than to the package, so this check runs only when you call it. |
| Check | Severity | Source |
|---|---|---|
browser_calls |
policy |
CRAN Policy: checks run non-interactively, so a debugging leftover such as browser() must not remain. |
file_operations |
policy |
CRAN Policy: “Packages should not write … anywhere … apart from the R session’s temporary directory”. Recipe: Writing Files and Directories to the Home Filespace. |
network_operations |
policy |
CRAN Policy: “Packages which use Internet resources should fail gracefully with an informative message if the resource is not available”. |
system_calls |
robustness |
No flat rule. Raw system() and system2() calls need review for portability, so they are not automatic violations. |
checktor has a check for every CRAN Cookbook recipe that describes a pattern in your sources. The two recipes without one describe things that no reading of the sources can settle.
Overall Checktime concerns a measurement. The NOTE reads “Overall checktime 20 min > 10 min”, and nothing in your sources tells how long they will take to run. R CMD check reports the figure, and the fix is fewer or smaller examples, vignettes and tests.
Communicating with CRAN is advice on writing to CRAN, including copying [email protected] and explaining yourself in cran-comments.md. Its one checkable part, whether that file exists, is cran_comments_file.
Severity records where a check’s authority sits, not how strongly checktor feels about it. Several checks are opinion because no authority backs them in either direction. Of those, title_starts_with_article, description_function_quotes and format_names stay callable but are left out of the default run for that reason. cph_role stays out because its own source says most authors need no cph role. cran_comments_file stays out because it asks about a submission workflow rather than the package.
If a finding contradicts your reading of the policy, look at its severity first. Opinion findings open a conversation and require nothing. To turn a check off for one package, list it in Config/checktor/disable in that package’s DESCRIPTION. To turn it off for every package, set options(checktor.disable = ...), for example in .Rprofile. Either way, the check does not run at all.