Zum Inhalt springen

Fix CodeCharter solution load failures and exit code 3

What exit code 3 means, why a run can silently analyze fewer methods than expected, and the checks to run in order.

codecharter analyze needs a working MSBuild workspace to open your .sln, .slnx, or .csproj before it can read a single type. When that step goes wrong, it shows up in one of two ways: a hard failure with exit code 3, or a quieter one where the run "succeeds" but analyzed less code than it should have.

Exit code 3: the run stops

Analysis failed: <exception message>

Exit code 3 means the solution or a project could not be loaded at all — the run never reaches rule evaluation. The most common trigger is a path that does not exist: pointing directly at a specific .sln/.csproj file that is not there causes the workspace to throw when it tries to open it.

This is different from passing a directory (or nothing) that contains no project at all — codecharter analyze walks the directory for a .sln, .slnx, or .csproj first, and when it finds none it exits with code 2 ("No .sln, .slnx, or .csproj file was found under ...") before it ever attempts to load anything. Exit code 3 is specifically about a target that was identified but failed to open.

See Exit Codes for the full table and codecharter analyze for the command's own summary.

The quieter failure: fewer methods than expected

A project can also open successfully through the design-time build while its own package restore is missing or stale. CodeCharter does not treat this as a load failure — analysis still runs and still exits based on findings — but every fact extracted from that project can be wrong, because its compilation could not resolve its own references. In particular, interface-implementation classification depends on resolving the interface type: a method that implements IEquatable<T> or one of your own custom interfaces can be missed, which then affects any rule built on that classification.

Symptoms to watch for:

  • codecharter analyze --verbose reports noticeably fewer types or methods than you expect for the size of the solution.
  • Findings that depend on interface implementation (or that a type implements a given interface at all) look wrong or are simply missing.
  • codecharter analyze --progress prints a line naming the affected project and noting that its NuGet restore may be missing or stale.

Because nothing here changes the exit code, this failure mode only surfaces in the run's own output — always check --verbose (and --progress for the per-project detail) when the finding count looks suspiciously low.

Checks, in order

  1. Confirm the path. Pass the path to the .sln, .slnx, or .csproj file explicitly rather than relying on directory discovery:

    codecharter analyze path/to/YourSolution.sln
    
  2. Restore, then build the whole solution. A partial or stale restore is the most common cause of the quieter failure above. Run a full restore and build before analyzing, matching what CI does on a clean checkout:

    dotnet restore
    dotnet build
    codecharter analyze path/to/YourSolution.sln
    

    Analyze the .sln rather than a single .csproj when the solution has multiple projects, so every project gets the same restore and build pass before analysis runs.

  3. Confirm the .NET SDK is installed and discoverable. CodeCharter opens the workspace through the .NET SDK's own MSBuild tooling. If no SDK is installed, or the solution targets a framework whose SDK/workload is missing, the workspace cannot be created at all. Check what is installed:

    dotnet --info
    dotnet --list-sdks
    
  4. Read the --verbose and --progress output. --verbose reports the rules directory used and the total number of types and methods found; a number far below what you expect points at the quieter failure above. Add --progress to also see a line per project as it is analyzed, including a note when a project's own restore looks broken:

    codecharter analyze path/to/YourSolution.sln --verbose --progress 2> codecharter.log
    

If the run still fails after these checks, collect the log and send it to us — see Collecting logs.

Where to go next