fsharp-analyzers 0.41.0

dotnet tool install --global fsharp-analyzers --version 0.41.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local fsharp-analyzers --version 0.41.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=fsharp-analyzers&version=0.41.0
                    
nuke :add-package fsharp-analyzers --version 0.41.0
                    

Ionide FSharp.Analyzers.SDK

Library used for building custom analyzers for FSAC / F# editors.

F# analyzers are live, real-time, project based plugins that enables to diagnose source code and surface custom errors, warnings and code fixes into editor. Read more about analyzers here - https://medium.com/lambda-factory/introducing-f-analyzers-772487889429

How to build

  1. Install the .NET SDK version specified in global.json
  2. dotnet tool restore
  3. Open and build in your favorite IDE, or use dotnet build

How to run sample

  1. dotnet build -c Release
  2. Run the console application:
dotnet run --project src\FSharp.Analyzers.Cli\FSharp.Analyzers.Cli.fsproj -- --project ./samples/OptionAnalyzer/OptionAnalyzer.fsproj --analyzers-path ./artifacts/bin/OptionAnalyzer/release --verbosity d

You can also set up a run configuration of FSharp.Analyzers.Cli in your favorite IDE using similar arguments. This also allows you to debug FSharp.Analyzers.Cli.

Using Analyzers

Checkout our Getting Started guide for analyzer users!

Upgrading with an AI agent

This repository ships an agent skill that upgrades the fsharp-analyzers tool and your analyzer packages to a matching set of versions, re-runs the analyzers and reports what is new. Install it globally with:

npx skills add ionide/FSharp.Analyzers.SDK --skill upgrade-fsharp-analyzers -g

Then ask your agent to "upgrade the F# analyzers" in a repository that uses them.

Writing Analyzers

Checkout our Getting Started guide for analyzer authors!

How to contribute

Imposter syndrome disclaimer: I want your help. No really, I do.

There might be a little voice inside that tells you you're not ready; that you need to do one more tutorial, or learn another framework, or write a few more blog posts before you can help me with this project.

I assure you, that's not the case.

This project has some clear Contribution Guidelines and expectations that you can read here.

The contribution guidelines outline the process that you'll need to follow to get a patch merged. By making expectations and process explicit, I hope it will make it easier for you to contribute.

And you don't just have to write code. You can help out by writing documentation, tests, or even by giving feedback about this work. (And yes, that includes giving feedback about the contribution guidelines.)

Thank you for contributing!

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests.

The library is available under MIT license, which allows modification and redistribution for both commercial and non-commercial purposes.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
0.41.0 0 10/16/2026
0.40.0 434 10/13/2026
0.39.2 17,575 9/12/2026
0.39.1 684 9/12/2026
0.39.0 4,535 9/10/2026
0.38.0 7,135 9/4/2026
0.37.2 133,040 6/17/2026
0.36.0 190,953 2/19/2026
0.35.0 12,927 1/24/2026
0.34.1 14,066 11/12/2025
0.33.1 17,320 10/19/2025
0.33.0 4,553 10/19/2025
0.32.1 8,463 8/2/2025
0.32.0 2,843 7/12/2025
0.31.0 28,866 5/17/2025
0.30.0 3,761 3/26/2025
0.29.1 1,148 3/7/2025
0.29.0 3,032 2/13/2025
0.28.0 22,503 11/19/2024
0.27.0 11,661 8/17/2024
Loading failed

### Added

- [A run where a project or script does not type check no longer looks clean outside the log](https://github.com/ionide/FSharp.Analyzers.SDK/issues/350). The SARIF report lists every type error as a `toolExecutionNotifications` entry and sets `executionSuccessful` to `false`. Pass `--fail-on-type-errors` to also exit with code `-5` (`TypeCheckFailed`) in that case. The switch is opt-in, so a run that analyzes before building keeps its exit code. A `#load` or `#r` in a script that cannot be resolved counts as a type error too.

### Changed

- *Breaking*: `Client.RunAnalyzersSafely` is now `Client.RunAnalyzers`, and the old `Client.RunAnalyzers`, which only returned the messages, is gone. It hid an analyzer that threw in the log, so a caller could not tell its messages were missing. `RunAnalyzers` returns an `AnalysisResult` per analyzer and does not throw. To get only the messages, collect the `Ok` outputs.
- *Breaking*: `AnalysisResult.Output` is now `Result<AnalyzerMessage list, exn>` instead of `Result<Message list, exn>`, so a caller keeps the name, help link and short description of the analyzer behind each message. Read `.Message` on each item to get the `Message` as before.
- An error from loading a script, such as a `#load` that cannot be resolved, is no longer logged at error level as `Script ... has a diagnostic`. It is logged with the type errors, as a warning under `did not type check`, and each type error now names its file and error code. A warning from loading a script is still logged as `Script ... has a diagnostic`, but at warning level instead of error level.

### Fixed

- File paths in the SARIF report and in `--output-format github` are relative to the code root. Without a trailing separator on `--code-root` (or the current directory, its default), every path started with the name of the code root directory, such as `repo/src/A.fs` instead of `src/A.fs`. A code root with a trailing separator is unaffected. GitHub code scanning re-creates open alerts once at the corrected paths, because it ties an alert to its file path.
- `--warnaserror`, which `TreatWarningsAsErrors` passes to the compiler, is ignored when type checking for the analyzers, so a warning no longer counts as a type error.
- An analyzer that throws no longer crashes the CLI. Its exception is logged, the other analyzers keep their messages, the SARIF report lists the failure as a `toolExecutionNotifications` entry with `executionSuccessful` set to `false`, and the CLI exits with `-4` (`AnalysisAborted`). Previously the run stopped with exit code `22`, without a SARIF report and without the messages of the other analyzers.
- An analyzer written as a function that throws before it returns its `Async` now reports its own exception, instead of a `TargetInvocationException` with the message `Exception has been thrown by the target of an invocation.`