Diagnostic
JETLS reports various diagnostic messages (errors, warnings, hints) to help you catch potential issues in your Julia code. Each diagnostic has a unique code that identifies its category and type.
This document describes all available diagnostic codes, their meanings, default severity levels, and how to configure them to match your project's needs.
Diagnostic codes
JETLS reports diagnostics using hierarchical codes in the format "category/kind", following the LSP specification. This structure allows fine-grained control over which diagnostics to show and at what severity level through configuration.
All available diagnostic codes are listed below. Each category (e.g., syntax/*, lowering/*) contains one or more specific diagnostic codes:
- Syntax diagnostic (
syntax/*) - Lowering diagnostic (
lowering/*) - Top-level diagnostic (
toplevel/*) - Inference diagnostic (
inference/*) - TestRunner diagnostic (
testrunner/*)
Diagnostic severity levels
Each diagnostic has a severity level that indicates how serious the issue is. JETLS supports four severity levels defined by the LSP specification:
Error(1): Critical issues that prevent code from working correctly. Most LSP clients display these with red underlines and error markers.Warning(2): Potential problems that should be reviewed. Typically shown with yellow/orange underlines and warning markers.Information(3): Informational messages about code that may benefit from attention. Often displayed with blue underlines or subtle markers.Hint(4): Suggestions for improvements or best practices. Usually shown with the least intrusive visual indicators.
How diagnostics are displayed depends on your LSP client (VS Code, Neovim, etc.), but most clients use color-coded underlines and gutter markers that correspond to these severity levels.
You can change the severity of any diagnostic by configuring diagnostic section. Additionally, JETLS supports disabling diagnostics entirely using the special severity value "off" (or 0).
Diagnostic reference
This section provides detailed explanations for each diagnostic code. For every diagnostic, you'll find:
- A description of what the diagnostic detects
- Its default severity level
- Code examples demonstrating when the diagnostic is reported
- Example diagnostic messages (shown in code comments)
Here is a summary table of the diagnostics explained in this section:
| Code | Default Severity | Description |
|---|---|---|
syntax/parse-error | Error | Syntax parsing errors detected by JuliaSyntax.jl |
lowering/error | Error | General lowering errors |
lowering/macro-expansion-error | Error | Errors during macro expansion |
lowering/unused-argument | Information | Function arguments that are never used |
lowering/unused-local | Information | Local variables that are assigned but never read |
toplevel/error | Error | Errors during code loading (missing deps, type failures, etc.) |
inference/undef-global-var | Warning | References to undefined global variables |
inference/undef-local-var | Information/Warning | References to undefined local variables |
testrunner/test-failure | Error | Test failures from TestRunner integration |
Syntax diagnostic (syntax/*)
Syntax parse error (syntax/parse-error)
Default severity: Error
Syntax parsing errors detected by JuliaSyntax.jl. These indicate invalid Julia syntax that prevents the code from being parsed.
Example:
function parse_error(x)
println(x # Expected `)` or `,` (JETLS syntax/parse-error)
endLowering diagnostic (lowering/*)
Lowering diagnostic is detected during Julia's lowering phase, which transforms parsed syntax into a simpler intermediate representation.
Lowering error (lowering/error)
Default severity: Error
General lowering errors that don't fit into more specific categories.
Example:
function lowering_error(x)
$(x) # `$` expression outside string or quote block (JETLS lowering/error)
endMacro expansion error (lowering/macro-expansion-error)
Default severity: Error
Errors that occur when expanding macros during the lowering phase.
Example:
function macro_expand_error()
@undefined_macro ex # Macro name `@undefined_macro` not found (JETLS lowering/macro-expansion-error)
endErrors that occur during actual macro expansion are also reported:
macro myinline(ex)
Meta.isexpr(ex, :function) || error("Expected long function definition")
return :(@inline $ex)
end
@myinline callsin(x) = sin(x) # Error expanding macro
# Expected long function definition (JETLS lowering/macro-expansion-error)Unused argument (lowering/unused-argument)
Default severity: Information
Function arguments that are declared but never used in the function body.
Example:
function unused_argument(x, y) # Unused argument `y` (JETLS lowering/unused-argument)
return x + 1
endUnused local variable (lowering/unused-local)
Default severity: Information
Local variables that are assigned but never read.
Example:
function unused_local()
x = 10 # Unused local binding `x` (JETLS lowering/unused-local)
return println(10)
endTop-level diagnostic (toplevel/*)
Top-level diagnostic are reported by JETLS's full analysis feature, which runs when you save a file. To prevent excessive analysis on frequent saves, JETLS uses a debounce mechanism. See the [full_analysis] debounce configuration documentation to adjust the debounce period.
Top-level error (toplevel/error)
Default severity: Error
Errors that occur when JETLS loads your code for analysis. This diagnostic is commonly reported in several scenarios:
- Missing package dependencies (the most frequent cause)
- Type definition failures
- References to undefined names at the top level
- Other errors during module evaluation
Examples:
struct ToplevelError # UndefVarError: `Unexisting` not defined in `JETLS`
# Suggestion: check for spelling errors or missing imports. (JETLS toplevel/error)
x::Unexisting
end
using UnexistingPkg # Package JETLS does not have UnexistingPkg in its dependencies:
# - You may have a partially installed environment. Try `Pkg.instantiate()`
# to ensure all packages in the environment are installed.
# - Or, if you have JETLS checked out for development and have
# added UnexistingPkg as a dependency but haven't updated your primary
# environment's manifest file, try `Pkg.resolve()`.
# - Otherwise you may need to report an issue with JETLS (JETLS toplevel/error)These errors prevent JETLS from fully analyzing your code, which means Inference diagnostic will not be available until the top-level errors are resolved. To fix these errors, ensure your package environment is properly set up by running Pkg.instantiate() in your package directory, and verify that your package can be loaded successfully in a Julia REPL.
Inference diagnostic (inference/*)
Inference diagnostic uses JET.jl to perform type-aware analysis and detect potential errors through static analysis. These diagnostics are also reported by JETLS's full analysis feature (see Top-level diagnostic for details on when analysis runs).
Undefined global variable (inference/undef-global-var)
Default severity: Warning
References to undefined global variables.
Example:
function undef_global_var()
return undefined_global # `undefined_global` is not defined (JETLS inference/undef-global-var)
endUndefined local variable (inference/undef-local-var)
Default severity: Information or Warning
References to undefined local variables. The severity depends on whether the variable is definitely undefined (Warning) or only possibly undefined (Information).
Example:
function undef_local_var()
if rand() > 0.5
x = 1
end
return x # local variable `x` may be undefined (JETLS inference/undef-local-var)
endTestRunner diagnostic (testrunner/*)
Test failure (testrunner/test-failure)
Default severity: Error
Test failures reported by TestRunner integration that happened during running individual @testset blocks or @test cases.
Configuring diagnostic
You can configure which diagnostics are shown and at what severity level under the [diagnostic] section. This allows you to customize JETLS's behavior to match your project's coding standards and preferences.
Common use cases
Suppress specific macro expansion errors:
[[diagnostic.patterns]]
pattern = "Macro name `MyPkg.@mymacro` not found"
match_by = "message"
match_type = "literal"
severity = "off"Apply different settings for test files:
# Downgrade unused arguments to hints in test files
[[diagnostic.patterns]]
pattern = "lowering/unused-argument"
match_by = "code"
match_type = "literal"
severity = "hint"
path = "test/**/*.jl"
# Disable all diagnostics for generated code
[[diagnostic.patterns]]
pattern = ".*"
match_by = "code"
match_type = "regex"
severity = "off"
path = "gen/**/*.jl"Disable unused variable warnings during prototyping:
[[diagnostic.patterns]]
pattern = "lowering/(unused-argument|unused-local)"
match_by = "code"
match_type = "regex"
severity = "off"Make inference diagnostic less intrusive:
[[diagnostic.patterns]]
pattern = "inference/.*"
match_by = "code"
match_type = "regex"
severity = "hint"For complete configuration options, severity values, pattern matching syntax, and more examples, see the [diagnostic] configuration section in the JETLS configuration page.