Repository navigation
Linter
Generated from 'wiki-linter.ts' on 2026-11-08, 08:41:45 UTC (v2.17.4, R v4.6.1), do not edit directly.
This page describes the flowR linter, which is a tool that utilizes flowR's dataflow analysis to find common issues in R scripts. The linter can currently be used through the linter query. Some rules also draw on the signature database. For example:
Running :query with @linter "read.csv(\"/root/x.txt\")" analyzes the code and returns any issues found.
Formatted more nicely, this returns:
[ { "type": "linter" } ](This can be shortened to @linter when used with the REPL command :query).
Results (prettified and summarized):
Query: linter (1435 ms)
╰ Deprecated Functions (deprecated-functions): no findings
╰ File Path Validity (file-path-validity):
╰ certain:
╰ Path /root/x.txt at 1.1-23
╰ Seeded Randomness (seeded-randomness): no findings
╰ Absolute Paths (absolute-file-paths):
╰ certain:
╰ Path /root/x.txt at 1.1-23
╰ Unused Definitions (unused-definitions): no findings
╰ Network Functions (network-functions): no findings
╰ Dataframe Access Validation (dataframe-access-validation): no findings
╰ Dead Code (dead-code): no findings
╰ Useless Loops (useless-loop): no findings
╰ Problematic Inputs (problematic-inputs): no findings
╰ Stop Without Call (stop-call): no findings
╰ Roxygen Arguments (roxygen-arguments): no findings
╰ No Leaked Credentials (no-leaked-credentials): no findings
╰ Undefined Symbol (undefined-symbol): no findings
╰ Unused Import (unused-import): no findings
╰ Unclosed Connection (unclosed-connection): no findings
╰ Overwritten File (overwritten-file): no findings
╰ Unescaped Arguments (unescaped-arguments): no findings
╰ Namespace Access Validity (namespace-access): no findings
╰ Secret Exfiltration (secret-exfiltration): no findings
╰ Process State in Session (process-state-in-session): no findings
Show Detailed Results as Json
The analysis ran (including parsing and normalization and the query) within the generation environment.
The JSON contains the ids of the nodes in question (see the Interface wiki page).
{"linter":{"results":{"deprecated-functions":{"results":[],".meta":{"builtin":0,"sigdb":0}},"file-path-validity":{"results":[{"involvedId":3,"loc":[1,1,1,23],"filePath":"/root/x.txt","certainty":"certain"}],".meta":{"totalReads":1,"totalUnknown":0,"totalWritesBeforeAlways":0,"totalValid":0}},"seeded-randomness":{"results":[],".meta":{"consumerCalls":0,"callsWithFunctionProducers":0,"callsWithAssignmentProducers":0,"callsWithNonConstantProducers":0,"callsWithOtherBranchProducers":0}},"absolute-file-paths":{"results":[{"certainty":"certain","filePath":"/root/x.txt","loc":[1,1,1,23]}],".meta":{"totalConsidered":1,"totalUnknown":0}},"unused-definitions":{"results":[],".meta":{"totalConsidered":0}},"network-functions":{"results":[],".meta":{"totalCalls":0,"totalFunctionDefinitions":0}},"dataframe-access-validation":{"results":[],".meta":{"numOperations":0,"numAccesses":0,"totalAccessed":0}},"dead-code":{"results":[],".meta":{}},"useless-loop":{"results":[],".meta":{"numOfUselessLoops":0}},"problematic-inputs":{"results":[],".meta":{}},"stop-call":{"results":[],".meta":{"consideredNodes":0}},"roxygen-arguments":{"results":[],".meta":{}},"no-leaked-credentials":{"results":[],".meta":{"totalChecked":1}},"undefined-symbol":{"results":[],".meta":{"totalFunctionCalls":1,"totalVariableUses":0,"suppressed":{"installed":0,"loadedPackage":0,"enclosingScope":0,"nonStandardEval":0,"subscript":0,"unresolvedLibrary":0,"declaredGlobal":0}}},"unused-import":{"results":[],".meta":{"totalConsidered":0,"totalUnresolved":0,"totalMultiPackage":0,"totalUnused":0}},"unclosed-connection":{"results":[],".meta":{"totalOpened":0,"totalClosed":0}},"overwritten-file":{"results":[],".meta":{"totalFiles":0}},"unescaped-arguments":{"results":[],".meta":{"totalCriticalArguments":0,"totalEscapedArguments":0}},"namespace-access":{"results":[],".meta":{"unresolved":0}},"secret-exfiltration":{"results":[],".meta":{"secretSinkCalls":0}},"process-state-in-session":{"results":[],".meta":{"sessionFunctions":0}}},".meta":{}},".meta":{}}Note
If you want to add a new linting rule, see Create Linting Rules.
The following linting rules are available, grouped by the kind of issue they find.
Badges link to the tags, steps of R CMD check to the conformance page.
Bugs (18), Smells (20), Style (1), Package Files (6)
| Rule | Finds | Tags |
|---|---|---|
| Bogus Return | a bare return (without ()), which evaluates to the function return instead of returningR CMD check 37 |
|
| Call Arguments | calls with arguments the called function does not take, names that match a formal only partially or match several formals, ... used in a function without ..., and local functions defined twice with different formalsR CMD check 37 |
|
| Class String Comparison |
if/while conditions comparing class(x) with a string, which fail for objects with several classesR CMD check 37 |
|
| Dataframe Access Validation | accesses to columns and rows a data frame does not have |
|
| Dependency Declaration | packages the code, tests, examples, or vignettes use without the DESCRIPTION declaring them, Imports nothing imports from, library() calls in package code, own ::: calls, and undeclared VignetteBuilder or RdMacros packagesR CMD check 27–33, 53, 77, 83, 85, 88 |
|
| Documentation Mismatch | exported objects without documentation, functions whose formals differ from their \usage, and arguments missing from or extra in \argumentsR CMD check 44, 48–50 |
|
| File Path Validity | file paths used in read and write operations that are invalid or do not point to existing files |
|
| Foreign Function Calls | problems in .Call, .C, .External, and .Fortran calls: a missing or empty PACKAGE, calls into base or other packages, and undeclared packagesR CMD check 40 |
|
| Global Environment Modification | code that changes the global environment: assign() or data() into it, attach(), <<- without a binding in an enclosing function, and <<- to a package variable, whose binding is locked at run timeR CMD check 37 |
|
| Namespace Access Validity |
pkg:::name where name is actually exported by pkg (so :: would do), and pkg::name where the signature database knows name is not exported (which fails at runtime in R)R CMD check 28 |
|
| Overwritten File | files the script writes more than once, so the later write replaces what the earlier one wrote, as two figures saved under the same name | |
| Package Hooks | problems in .onLoad, .onAttach, .onDetach, and .Last.lib: argument lists, attaching packages, output other than packageStartupMessage(), installed.packages(), misplaced library.dynam() calls, and the obsolete .First.libR CMD check 37, 42–44, 82 |
|
| Package Runtime | what makes installing, loading, or running the package fail without doing so: undefined exports, export patterns matching nothing, a NAMESPACE exporting nothing, S3 methods without a function, bad NAMESPACE imports, a package attaching itself, tests that never run, test or vignette code that does not parse, missing vignette metadata, and files written into the working directory R CMD check 4–5, 7, 33, 77, 79–81, 83–87, 89–91 |
|
| Process State in Session | per-session Shiny code changing state all sessions share: globals, options, environment variables, the working directory, namespaces, top-level reactive values, shared caches (memoise, bindCache, cachem) whose key misses session values, and resource paths |
|
| S3 Method Consistency | S3 methods whose formals do not match their generic, methods not registered in the NAMESPACE, and replacement functions whose last formal is not valueR CMD check 38–39, 41 |
|
| Secret Exfiltration | secrets (environment, keyrings, config, credential files) sent to untrusted hosts, the browser, or logs, and optionally into urls, files, other processes, or language models |
|
| Syntactically Valid | syntax errors with the configured (error-tolerant) parser R CMD check 35 |
|
| Undefined Symbol | functions and variables that are neither defined locally, a base R builtin, nor exported by a loaded package R CMD check 37 |
| Rule | Finds | Tags |
|---|---|---|
| Absolute Paths | absolute file paths |
|
| Code Clones | duplicated code (code clones) with a configurable selection of AST, token, and fingerprint based algorithms |
|
| Dead Code | code that is never reached during execution |
|
| Deprecated Functions | deprecated functions and deprecated arguments of still-current functions, offering the replacement as a quick fix where one is known R CMD check 37 |
|
| Namespace Tampering |
unlockBinding() and assignInNamespace() on other namespaces, .Internal() calls, and library.dynam() given a file extensionR CMD check 37 |
|
| Network Functions | functions that execute network operations, such as downloading files or making HTTP requests |
|
| No Leaked Credentials | hardcoded credentials assigned to variables or passed as arguments whose names suggest they hold passwords, tokens, or API keys, handed to authentication functions, or whose values match known credential formats (AWS, GitHub, Slack, Stripe, Google, JWT, SSH, URLs with passwords) |
|
| Non-ASCII Code | non-ASCII characters in R code and the NAMESPACE outside of comments R CMD check 36, 44 |
|
| Problematic Inputs | dynamic calls (e.g. eval, system) with non-constant inputs, and graphics-device calls (pdf, postscript) where a filename starts with '|' indicating a pipe command injection |
|
| Roxygen Arguments | function parameters the roxygen documentation leaves out, and documented parameters the function does not have | |
| Seeded Randomness | randomness-based function calls not preceded by a random seed generation function |
|
| Software Has License | software projects without a license (a LICENSE file or the License field of the DESCRIPTION) R CMD check 25 |
|
| Software Has Tests | software projects without tests (test files in a test directory or test function calls in R code) R CMD check 24 |
|
| Stop Without Call |
stop() calls that do not set call. to FALSE
|
|
| TRUE/FALSE Abbreviation |
T and F used for TRUE and FALSE, and top-level definitions of T or FR CMD check 37 |
|
| Unclosed Connection | connections that are opened but not closed on every path opening them |
|
| Unescaped Arguments | arguments of critical system, evaluation, database, and HTML/JavaScript calls that are not properly escaped |
|
| Unused Definitions | definitions that are never used |
|
| Unused Import | packages that are attached but never used, so the code runs just the same without them |
|
| Useless Loops | loops that iterate only once |
| Rule | Finds | Tags |
|---|---|---|
| Naming Convention | symbols that do not follow the naming convention of the code |
| Rule | Finds | Tags |
|---|---|---|
| Compiled Code | problems in src/ and the build files: non-portable Makevars flags, BLAS/LAPACK and OpenMP flag use, GNU make extensions, pragmas, line endings, Fortran KIND, the C++ standard, calls to non-API or non-portable entry points, and useDynLib against src/R CMD check 20, 65–78 |
|
| Description Metadata | problems in the DESCRIPTION: required fields, package name, version, maintainer, dependency fields, license, Authors@R, encoding, and the Title and Description style CRAN asks for R CMD check 1, 6, 25–27 |
|
| Package Data | problems in data/ and R/sysdata.rda: allowed file types, LazyData, compression, the serialization version R needs, and undocumented data setsR CMD check 34, 48, 60–64 |
|
| Package Metafiles | problems in the demo index, INDEX, inst/CITATION, and relative links in README, NEWS, and vignettesR CMD check 56–59 |
|
| Package Structure | problems in the package files: portable names, hidden files, top-level files, subdirectories, permissions, executables, timestamps, sizes, line endings of scripts, and vignette leftovers R CMD check 2–3, 8–23, 57, 87 |
|
| Rd Files | problems in the Rd files: syntax, unknown macros, required and duplicated sections, metadata, cross-references, line widths, contents, and the example code R CMD check 45–47, 50–55, 88–92 |
|
Rules tagged attach a
LintQuickFix to their results,
describing the edit that resolves the finding. flowR does not only report them, it carries them out:
byFile collects the fixes of a lint run per file and apply
returns that file's content with them applied. Of two overlapping fixes only the one coming first in the file is kept,
and a removal that leaves nothing but whitespace behind takes its line with it.
In LinterOutputFormat::Sarif output the fixes become SARIF fixes, which an editor
or code scanner can offer directly. LinterOutputFormat::Github annotations carry no
fix of their own, so the descriptions are appended to the message.
We use tags to categorize linting rules for users. The following tags are available:
| Tag/Badge | Description |
|---|---|
|
|
This rule is used to detect bugs in the code. Everything that affects the semantics of the code, such as incorrect function calls, wrong arguments, etc. is to be considered a bug. Otherwise, it may be a smell or a style issue. (rules: file-path-validity, dataframe-access-validation, undefined-symbol, syntactically-valid, overwritten-file, namespace-access, class-string-comparison, documentation-mismatch, bogus-return, package-hooks, global-environment-modification, s3-method-consistency, foreign-function-calls, dependency-declaration, call-arguments, package-runtime, secret-exfiltration, and process-state-in-session) |
|
|
This signals the use of deprecated functions or features. (rule: deprecated-functions) |
|
|
This rule is used to detect issues that are related to the documentation of the code. For example, missing or misleading comments. (rules: roxygen-arguments, software-has-license, and documentation-mismatch) |
|
|
This marks rules which are currently considered experimental, not that they detect experimental code. (rules: no-leaked-credentials, undefined-symbol, and code-clones) |
|
|
This rule is used to detect issues that are related to the performance of the code. For example, inefficient algorithms, unnecessary computations, or unoptimized data structures. (rules: network-functions and problematic-inputs) |
|
|
This rule is used to detect issues that are related to the portability of the code. For example, platform-specific code, or code that relies on specific R versions or packages. (rules: file-path-validity, seeded-randomness, absolute-file-paths, syntactically-valid, unclosed-connection, class-string-comparison, true-false-abbreviation, global-environment-modification, namespace-tampering, s3-method-consistency, foreign-function-calls, call-arguments, package-metafiles, rd-files, and package-runtime) |
|
|
The rule is specific to R version 3.x. (rules: none) |
|
|
The rule is specific to R version 4.x. (rules: none) |
|
|
This rule is used to detect issues that are related to the readability of the code. For example, complex expressions, long lines, or inconsistent formatting. (rules: unused-definitions, useless-loop, problematic-inputs, unused-import, true-false-abbreviation, and code-clones) |
|
|
This rule is used to detect issues that are related to the reproducibility of the code. For example, missing or incorrect random seeds, or missing data. (rules: deprecated-functions, file-path-validity, seeded-randomness, absolute-file-paths, network-functions, dataframe-access-validation, dead-code, software-has-tests, overwritten-file, and dependency-declaration) |
|
|
This rule is used to detect security-critical. For example, missing input validation. (rules: network-functions, problematic-inputs, no-leaked-credentials, unescaped-arguments, namespace-tampering, secret-exfiltration, and process-state-in-session) |
|
|
This rule is used to detect issues that are related to the shiny framework. (rules: unescaped-arguments, secret-exfiltration, and process-state-in-session) |
|
|
This rule is used to detect issues that do not directly affect the semantics of the code, but are still considered bad practice. (rules: deprecated-functions, seeded-randomness, absolute-file-paths, unused-definitions, network-functions, dead-code, useless-loop, problematic-inputs, stop-call, roxygen-arguments, software-has-license, software-has-tests, no-leaked-credentials, unused-import, unclosed-connection, unescaped-arguments, non-ascii-code, true-false-abbreviation, namespace-tampering, and code-clones) |
|
|
This rule is used to detect issues that are related to the style of the code. For example, inconsistent naming conventions, or missing or incorrect formatting. (rule: naming-convention) |
|
|
This rule is used to detect issues that are related to the (re-)usability of the code. For example, missing or incorrect error handling, or missing or incorrect user interface elements. (rules: deprecated-functions, dataframe-access-validation, dead-code, software-has-license, software-has-tests, and package-hooks) |
|
|
This rule ports a check of R CMD check (see the "Checking packages" section of the "Writing R Extensions" manual), so it only makes sense for an R package. Rules with this tag are only part of the default rule set when the analyzed project is a package (see the linter.disabledTags option of the flowR config). (rules: class-string-comparison, description-metadata, documentation-mismatch, non-ascii-code, true-false-abbreviation, bogus-return, package-hooks, global-environment-modification, namespace-tampering, s3-method-consistency, foreign-function-calls, dependency-declaration, call-arguments, package-structure, compiled-code, package-metafiles, rd-files, package-data, and package-runtime) |
|
|
This rule may provide quickfixes to automatically fix the issues it detects. (rules: deprecated-functions, file-path-validity, absolute-file-paths, unused-definitions, naming-convention, dead-code, stop-call, unused-import, syntactically-valid, unclosed-connection, unescaped-arguments, namespace-access, class-string-comparison, non-ascii-code, true-false-abbreviation, bogus-return, package-hooks, and call-arguments) |
Both linting rules and their individual results are additionally categorized by how certain the linter is that the results it is returning are valid.
Rules tagged port
R CMD check, they run by default only for packages (config option linter.disabledTags).
The R CMD check conformance page lists every step of R CMD check, the rules covering it, and how far they go.
Currently maintained by Florian Sihler and Oliver Gerstl at Ulm University
Email | GitHub | Penguins | Portfolio
- 🧑💻 Developer Onboarding
- 💻 Setup
- 👓 Overview
- 🪟 Interfacing with flowR
- 🌋 Core
- 🧹 Testing & Linting (Benchmark Page)
⁉️ FAQ- ℹ️ Extra Information