Skip to content

Diagnostic codes

Every finding ry reports carries a stable code. This page lists all of them.

warning[unresolved]: I could not resolve `validte_url` in this package, its imports, or builtins. Did you mean `validate_url`?
--> R/a.R:2:22
2 | check <- function(x) validte_url(x)
^^^^^^^^^^^
PartMeaning
warningSeverity — warning or error. --min-severity error reports only errors and exits on them alone
[unresolved]The diagnostic code. Stable across message rewordings: it is what you name in a suppression comment, in ry.toml, and what --output json reports as code
R/a.R:2:22File, line, and character column of where the finding starts
^^^^The exact source range the finding is about — the name, the token, or the expression, not the whole statement

Some findings add a related location on a following line, as = note:duplicate uses it to point at the other definition. See the CLI reference for the JSON shape.

A # ry: allow(...) comment silences findings whose range starts on its own line (as a trailing comment) or on the line directly below it. There is no block or file scope.

CommentSilences
# ry: allow(unused)The one named code
# ry: allow(unused, naming-style)Every listed code
# ry: allow(all)Every code
# ry: allow(unused)
scratch <- 1L
total = 1L # ry: allow(assignment-operator)
flag <- T ## ry: allow(all)

The marker is found by a line scan, not a parse: the first # on the line, all leading # stripped, then the literal ry: and allow( up to the first ). So ## ry: allow(x) and #ry:allow(x) both work — but a # inside a string literal earlier on the line moves where the scan starts.

Not suppressible, because these are not reported against an R source file: stub (reported on .Rtypes), config, and the unresolved / unused-import findings reported on NAMESPACE.

DirectiveEffectScope
# typing: offTurns type checking off for this file, overriding [check] typingFile; must be a top-level comment
# typing: onTurns type checking on for this fileFile
# typing: strict or #: @strictTurns on type checking and strict mode for this fileFile

# typing: off does not silence annotation findings — a malformed #: comment is reported whether or not the file is type-checked. An unrecognized value such as # typing: onn is itself reported as an annotation error.

Several R idioms are recognized directly, with no comment needed:

ConstructEffect
globalVariables(c("a", "b")) at top levelThose names never report unresolved, project-wide
A file that calls R6Classself, private and super resolve in it
A name created by <<- anywhere in the fileResolves
A name starting with . or _Never reports unused
library(pkg) for a package with no shipped stubunresolved goes quiet, except for near misses of names your own project binds

Formatting is suppressed by a different mechanism — # fmt: skip, # fmt: off / # fmt: on, # fmt: skip-file. See formatting rules.

Most codes are on by default. These are the opt-ins, all configured in ry.toml:

CodeTurn on with
type-mismatch[check] typing = true, or # typing: on in the file
strict[check] strict = true, or # typing: strict in the file
naming-style[lint] naming-style = "snake_case" or "camelCase"
unused-parameter[lint] unused-parameter = "warn" or "error"
unused-import[lint] unused-import = "warn" or "error"
shadows-builtin[lint] shadows-builtin = "warn" or "error"
shadows-namespace[lint] shadows-namespace = "warn" or "error"

To go the other way: [check] unused = false, and any [lint] code set to "off".

CodeSeverityOn by defaultTriggered by
syntax-errorerroryesAnything the R parser rejects. The message varies with the failure (“unclosed (; expected ) to close the parameter list”); the code does not
syntax-errorerroryesA type expression inside a #: annotation that does not parse

A statement that fails to parse as R suppresses every name-resolution and typing finding overlapping it — the checker draws no conclusions from source it could not read. A broken annotation does not suppress anything.

CodeSeverityOn by defaultTriggered by
unresolvedwarningyesA bare name read that resolves nowhere: not a local, not a top-level definition in this package, not a NAMESPACE import, not a builtin or stub export. Adds Did you mean for a near miss
unresolvedwarningyespkg::name where the stub corpus knows pkg but pkg does not export name. pkg:::name is exempt — it legitimately reaches unexported names
unresolvedwarningyespkg::name where pkg is neither a stub namespace nor a declared DESCRIPTION dependency: “unknown package namespace notapackage
unresolvederroryesIn NAMESPACE: importFrom(pkg, name) where pkg has stubs and does not export name. An error rather than a warning because R refuses to load the package
unresolvederroryes (check only)In NAMESPACE: export(name) naming something the package defines nowhere at top level — R CMD check’s “undefined exports”. Not reported by the language server
unusedwarningyesA write inside a function body that no read ever reaches, including a store overwritten before every read
unusedwarningyesIn a script, a top-level binding nothing later reads. Package files are exempt — any file may use them. S3 method names are exempt: dispatch is not a read
duplicatewarningyesA top-level name defined more than once across a package’s files. Both sites report, each with a note pointing at the other. Scripts are exempt — rebinding in a sequential script is ordinary

annotation covers malformed #: comments and is always on. type-mismatch and strict are opt-in; see type-system reference for the semantics behind them.

CodeSeverityOn by defaultTriggered by
annotationerroryesA type name that is not a builtin, a declared @type/@alias, or a stub class. Adds Did you mean
annotationerroryesA malformed block: @forall after @param, @param after @return, more than one @return, a duplicate type-parameter name, @new with no nominal, or an unknown constraint (only numeric and atomic exist)
annotationerroryesA dangling #: — no expression on the next line, a blank line in between, or no type expression at all
annotationerroryesType-argument arity: arguments applied to a non-generic, the wrong number of them, or a bare reference to a generic that needs them
annotationerroryesA @type/@alias block that is not at file top level; @new naming an @alias rather than a @type; the same type name declared twice anywhere in the project (@type and @alias share one project-wide namespace)
annotationerroryesAn unrecognized # typing: directive value
type-mismatcherrornoAn argument, or a returned value, whose type does not match the declared one
type-mismatcherrornoCalling something that is not a function, or a callee that may be NULL
type-mismatcherrornoToo many positional arguments, or a required argument missing
type-mismatcherrornoAn argument name the function has no parameter for, or supplied twice. Names the parameter list and suggests the nearest match
type-mismatcherrornoNo overload of an overloaded function matches the call
type-mismatcherrorno$ or [[ naming a field or position that does not exist (with a suggestion), or $ on an atomic vector
type-mismatcherrorno[[ on something that is not a list, an index that is not valid for the vector, or an index shape that is not modeled — x[], a named index, a multi-index (matrix and data-frame subsetting)
type-mismatcherrornoAn operator applied to an operand, or a pair of operands, it is not defined for
type-mismatcherrornofor over something that is not a sequence
type-mismatcherrornoA constraint violated: numeric, atomic, or a scalar numeric
type-mismatcherrornoAn alias cycle, or an infinite type (the occurs check)
type-mismatcherrornoAnnotation rules: @if-unknown where the type is already known, an annotated parameter that also has a default, annotation parameters that do not match the function’s formals, or a []/[named] element type that is not atomic
stricterrornoAn expression whose type is undetermined — “this expression has an undetermined type (Unknown)”
stricterrornoA reference with no known type — “could not determine the type of x
stricterrornoA binding whose type does not stabilize across loop iterations
stricterrornoA binding defined recursively

Enabling strict also raises every unresolved finding in the file from warning to error. The count does not change; the severity does, which matters if --min-severity error gates your build.

CodeSeverityOn by defaultTriggered by
assignment-operatorwarningyes= used as assignment. The range is the = token alone
boolean-shorthandwarningyesAn identifier that is exactly T or F. Identifiers inside #: annotations are exempt, so a type variable named T is fine
trailing-commaerroryesA comma after a call’s last argument. In R this supplies a missing argument rather than being ignored — hence error, unlike the other default-on lints
naming-stylewarningnoAn assignment target or a function parameter that does not match the configured casing. SCREAMING_SNAKE_CASE conforms under either style. Always a warning: the "warn"/"error" levels do not apply to this lint, which is configured by style value instead
unused-parameteras configurednoA formal no read resolves to. ... is exempt, and S3 generics and their methods are exempt entirely — their formals are dictated by the generic
unused-importas configurednoAn importFrom(pkg, name) in NAMESPACE whose name appears in no token of any checked source. Whole-namespace import(pkg) is never checked. Reported by check only, not by the language server
shadows-builtinas configurednoA top-level binding whose name base exports. Requires stubs to be installed
shadows-namespaceas configurednoA top-level binding whose name a non-base stub namespace declares and that resolves bare (stats::filter, utils::head)

missing-comma is retired and never emitted — the parser rejects f(1 2) as a syntax error, exactly as R does. The config key still parses so old configs keep loading, and is ignored.

CodeSeverityOn by defaultTriggered by
stuberroryesA declaration in a project’s stubs/*.Rtypes file that would otherwise be dropped in silence: a line that is not a name : TYPE declaration, an invalid name, a missing or invalid type, an unknown type name, or @masked on a non-variadic function type. The range covers the whole line
configerroryesA malformed ry.toml — a TOML parse failure, or the wrong type of value on a known key. Reported on the config file by the language server only; check reports config failures as a usage error with exit code 2. An unknown key is not this finding: it is a check warning on stderr and never blocks loading