Diagnostics Reference
Infr produces diagnostics (errors and warnings) when it detects issues in your code. Each diagnostic includes a source location, description, and often a suggestion for how to fix it.
Parse errors
If Infr cannot parse your file (e.g. unsupported syntax or malformed expressions), a parse error diagnostic is reported at the location of the issue. This applies both to the CLI (infr check) and the LSP (VS Code extension).
# Example parse error — unsupported syntax will show:
# Error: Parse error at line N, col M: ...
Type errors
Const reassignment
const x <- 5
x <- 10
# Error [infr]: Cannot reassign const binding `x` (declared at line 1)
Fix: Use let if you need to reassign, or remove the reassignment.
Type mismatch in arguments
const add <- function(x: numeric, y: numeric) -> numeric { x + y }
add("hello", 5)
# Error [infr] at line 2: Type mismatch in argument `x` of `add()`.
# Expected: numeric
# Got: character
Fix: Pass a value of the correct type.
Type mismatch in assignment
const x: numeric <- "hello"
# Error [infr]: Cannot assign character to numeric
Fix: Change the annotation or the value.
Return type mismatch
add <- function(x: numeric, y: numeric) -> character {
x + y
}
# Error [infr]: Return type mismatch. Expected character, got numeric.
Fix: Change the return type annotation to match the actual return type.
Nullable access (strict mode)
const val: numeric? <- maybe_get()
val + 1
# Error [infr]: Cannot pass numeric? to `+` which expects numeric. Check for NULL first.
Fix: Add a null check:
if (!is.null(val)) {
val + 1 # OK
}
Nonexistent field/column
const df: data.frame<{x: numeric}> <- data.frame(x = 1:3)
df$y
# Error [infr]: Column `y` does not exist on data.frame<{x}>
Fix: Use a column that exists, or update the type annotation.
Binding requires const or let (strict mode)
x <- 10
# Error [infr]: Must use const or let (strict mode)
Fix: Use const x <- 10 or let x <- 10.
Type alias mismatch
type Name = character
const bad: Name <- 42
# Error [infr]: Type mismatch
Fix: Provide a value matching the aliased type.
Literal type mismatch
type Greeting = "hello" | "goodbye"
const g: Greeting <- "hi"
# Error [infr]: Type mismatch
Fix: Use one of the allowed literal values.
NA comparison
x == NA
# Error [infr]: Comparison with NA always returns NA. Use is.na() instead.
x != NA
# Error [infr]: Comparison with NA always returns NA. Use !is.na() instead.
Fix: Use is.na(x) or !is.na(x).
Incompatible type comparison
const x: character <- "hello"
const y: numeric <- 5
x == y
# Error [infr]: Cannot compare character with numeric.
Fix: Ensure both sides of a comparison are of compatible types. Types within the numeric hierarchy (logical, integer, numeric, complex) are mutually comparable.
sapply() inside functions
my_func <- function(x: list) {
sapply(x, length)
# Error [infr]: sapply() has unpredictable return types. Use vapply() or lapply() instead.
}
Fix: Replace sapply() with vapply() (type-safe) or lapply() (always returns a list). This check only applies inside function bodies, where type stability matters most.
Warnings
Const mutation
const df <- data.frame(x = 1:3)
df$y <- 4:6
# Warning [infr]: Mutating const binding `df` via `$<-`.
Consider const or let (moderate mode)
x <- 10
# Warning [infr]: Consider using const or let for explicit intent
Nullable access (moderate mode)
const val: numeric? <- maybe_get()
val + 1
# Warning [infr]: `val` is numeric? (nullable). Consider checking for NULL first.
Suppressing diagnostics
- Single line: Add
# @infr-ignoreon the line before - Entire file: Add
# @infr-nocheckat the top - Per-binding: Use the
anytype
See Escape Hatches for details.