Skip to content
Development
Skill

/migrate-nullable-references

Enable nullable reference types in a C# project and systematically resolve all warnings. USE FOR: adopting NRTs in existing codebases, file-by-file or project-wide migration, fixing CS8602/CS8618/CS86xx warnings, annotating APIs for nullability, cleaning up null-forgiving

From plugin
dotnet-skills
499200 skills17 agents

Claude Code

$ npx -y skills add managedcode/dotnet-skills --skill migrate-nullable-references --agent claude-code

SKILL.md

migrate-nullable-references.SKILL.md
name: migrate-nullable-references
description: >
  Enable nullable reference types in a C# project and systematically resolve all warnings.
  USE FOR: adopting NRTs in existing codebases, file-by-file or project-wide migration,
  fixing CS8602/CS8618/CS86xx warnings, annotating APIs for nullability, cleaning up
  null-forgiving operators, upgrading dependencies with new nullable annotations.
  DO NOT USE FOR: projects already fully migrated with zero warnings (unless auditing
  suppressions), fixing a handful of nullable warnings in code that already has NRTs enabled,
  suppressing warnings without fixing them, C# 7.3 or earlier projects.
  INVOKES: Get-NullableReadiness.ps1 scanner script.
license: MIT

Nullable Reference Migration

Enable C# nullable reference types (NRTs) in an existing codebase and systematically resolve all warnings. The outcome is a project (or solution) with `<Nullable>enable</Nullable>`, zero nullable warnings, and accurately annotated public API surfaces — giving both the compiler and consumers reliable nullability information.

When to Use

  • Enabling nullable reference types in an existing C# project or solution
  • Systematically resolving CS86xx nullable warnings after enabling the feature
  • Annotating a library's public API surface so consumers get accurate nullability information
  • Upgrading a dependency that has added nullable annotations and new warnings appear
  • Analyzing suppressions in a code base that has already enabled NRTs to determine whether they can be removed

When Not to Use

  • The project already has `<Nullable>enable</Nullable>` and zero warnings — the migration is done unless the user wants to re-examine suppressions with a view to removing unnecessary ones (see Step 6)
  • The user only wants to suppress warnings without fixing them (recommend against this)
  • The code targets C# 7.3 or earlier, which does not support nullable reference types

Inputs

| Input | Required | Description | |-------|----------|-------------| | Project or solution path | Yes | The `.csproj`, `.sln`, or build entry point to migrate | | Migration scope | No | `project-wide` (default) or `file-by-file` — controls the rollout strategy | | Build command | No | How to build the project (e.g., `dotnet build`, `msbuild`, or a repo-specific build script). Detect from the repo if not provided | | Test command | No | How to run tests (e.g., `dotnet test`, or a repo-specific test script). Detect from the repo if not provided |

Workflow

> 🛑 **Zero runtime behavior changes.** NRT migration is strictly a metadata and annotation exercise. The generated IL must not change — no new branches, no new null checks, no changed control flow, no added or removed method calls. The only acceptable changes are nullable annotations (`?`), nullable attributes (`[NotNullWhen]`, etc.), `!` operators (metadata-only), and `#nullable` directives. If you discover a missing runtime null guard or a latent bug during migration, **do not fix it inline**. Instead, offer to insert a `// TODO: Consider adding ArgumentNullException.ThrowIfNull(param)` comment at the site so the user can address it as a separate change. Never mix behavioral fixes into an annotation commit.

> **Commit strategy:** Commit at each logical boundary — after enabling `<Nullable>` (Step 2), after fixing dereference warnings (Step 3), after annotating declarations (Step 4), after applying nullable attributes (Step 5), and after cleaning up suppressions (Step 6). This keeps each commit focused and reviewable, and prevents losing work if a later step reveals a design issue that requires rethinking. For file-by-file migrations, commit each file or batch of related files individually.

Step 1: Evaluate readiness

> **Optional:** Run `scripts/Get-NullableReadiness.ps1 -Path <project-or-solution>` to automate the checks below. The script reports `<Nullable>`, `<LangVersion>`, `<TargetFramework>`, `<WarningsAsErrors>` settings and counts `#nullable disable` directives, `!` operators, and `#pragma warning disable CS86xx` suppressions. Use `-Json` for machine-readable output.

1. Identify how the project is built and tested. Look for build scripts (e.g., `build.cmd`, `build.sh`, `Makefile`), a `.sln` file, or individual `.csproj` files. If the repo uses a custom build script, use it instead of `dotnet build` throughout this workflow. 2. Run `dotnet --version` to confirm the SDK is installed. Nullable reference types (NRTs) require C# 8.0+ (`.NET Core 3.0` / `.NET Standard 2.1` or later). 3. Open the `.csproj` (or `Directory.Build.props` if properties are set at the repo level) and check the `<LangVersion>` and `<TargetFramework>`. If the project multi-targets, note all TFMs.

> **Stop if the language version or target framework is insufficient.** If `<LangVersion>` is below 8.0, or the project targets a framework that defaults to C# 7.x (e.g., `.NET Framework 4.x` without an explicit `<LangVersion>`), NRTs cannot be enabled as-is. Inform the user explicitly: explain what needs to change (set `<LangVersion>8.0</LangVersion>` or higher, or retarget to `.NET Core 3.0+` / `.NET 5+`), and ask whether they want to make that update and continue, or abort the migration. Do not silently proceed or assume the update is acceptable. 4. Check whether `<Nullable>` is already set. If it is set to `enable`, skip to Step 5 to audit remaining warnings. 5. Determine the project type — this shapes annotation priorities throughout the migration:

  • **Library**: Focus on public API contracts first. Every `?` on a public parameter or return type is a contract change that consumers depend on. Be precise and conservative.
  • **Application (web, console, desktop)**: Focus on null safety at boundaries — deserialization, database queries, user input, external API responses. Internal plumbing can be annotated more liberally.
  • **Test project**: Lower priority for annotation precision. Use `!` more freely on test setup and assertions whe
Read more
@managedcode
Ships withdotnet-skills

Stop explaining .NET to your AI. Start building. We've all been there: asking Claude to use Entity Framework, only to get EF6 patterns in a .NET 8 project. Explaining to Copilot that Blazor Server and Blazor WebAssembly aren't the same thing.

499200 skills17 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
499
Star history of managedcode/dotnet-skills on GitHub, a chart by star-history.com

Other skills on dotnet-skills.

aspnet-core

aspnet-core

Build, debug, modernize, or review ASP.NET Core applications with correct hosting, middleware, security, configuration, logging,…

aspire

aspire

Build, upgrade, and operate Aspire 13.5.x C# or TypeScript application hosts with the current CLI, AppHost, ServiceDefaults,…

avalonia

avalonia

Build and debug Avalonia 11/12 .NET applications with XAML, compiled bindings, MVVM, custom controls, desktop lifetimes, and…

azure-functions

azure-functions

Build, review, or migrate Azure Functions in .NET with correct execution model, isolated worker setup, bindings, DI, and Durable…

blazor

blazor

Build and review Blazor applications across server, WebAssembly, web app, and hybrid scenarios with correct component design,…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about migrate-nullable-references.

Which coding agents can use migrate-nullable-references?
migrate-nullable-references installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.