Skip to content
Purview Dev logo

Diagnostics

Stable Aspire ResourceKit Reviewed 2026-09-16 purview-dev/aspire-resourcekit Star on GitHub 2 apphost aspire cloud-native code-generation csharp developer-tools distributed-systems dotnet dotnet-aspire integration-testing resource-management roslyn source-generators testing

ResourceKit reports diagnostics with SGxxxx IDs to help you fix model issues quickly. The rules are evaluated by the bundled ResourceKitDiagnosticAnalyzer (and the source generator uses the same shared rule set to decide what can be generated).

ResourceKit also ships ResourceKitDiagnosticSuppressor, which automatically suppresses CS8618 for non-nullable IResourceBuilder<T> properties declared on resource kits — these are populated at runtime during the BuildResource/ConfigureResource lifecycle, so the “must contain a non-null value when exiting the constructor” warning does not apply.

IDSeverityWhat it means
SG0001ErrorA participating class must be partial
SG0002InfoHost kit exists but no resources were defined
SG0003WarningResources exist but no host kit was defined
SG0004ErrorMore than one [HostKit] class was found
SG0005ErrorTwo resources map to the same generated property name
SG0006ErrorA resource does not derive from the expected generated base
SG0007ErrorResource name could not be inferred and Name was not set
SG0008ErrorExplicit PropertyName is not a valid C# identifier
SG0009ErrorMissing IServiceCollection dependency
SG0010ErrorMissing configuration binder dependency
SG0011ErrorMissing options configuration extensions dependency
SG0012ErrorNon-empty constructors are not supported on attributed classes
SG0013ErrorMixed ResourceDefinition and ResourceDefinition<TResource> usage on one class
SG0014ErrorNon-generic ResourceDefinition requires explicit compatible base type
SG0015ErrorGeneric ResourceDefinition<TResource> cannot declare explicit base type
SG0016ErrorNo Aspire resource type could be inferred/found
SG0017WarningAn IResourceBuilder<T> property is never assigned in BuildResource or ConfigureResource
SG0018WarningA project resource kit does not add the declared project via AddProject<T>()
SG0019WarningA project resource kit declares an explicit base class that does not use ProjectResource
SG0020ErrorAn OptionsHelper.Assign action sets more than one property path

See Attributes Reference for the rules tied to attribute styles, and Project Resources for SG0018/SG0019 specifics.

Execution-only vs generation-blocking rules

Section titled “Execution-only vs generation-blocking rules”

SG0017, SG0018, and SG0019 are execution-only rules. They report problems that break the resource at runtime (an unset builder property, a project that is never registered, or a base class that cannot build a project) but they do not prevent source generation. They are reported as warnings so generation always proceeds — for example, a resource kit whose BuildResource does not yet register its declared project via AddProject<T>() is still generated (and the host kit is still emitted) so the user can complete the override instead of losing the whole output. Only Error-severity rules (SG0001–SG0016) block generation.

OptionsHelper.Assign action with multiple property paths (SG0020)

Section titled “OptionsHelper.Assign action with multiple property paths (SG0020)”

Each OptionsHelper.Assign<TOptions>(...) action must set exactly one property path. A block-bodied lambda such as the following is rejected at compile time:

OptionsHelper.Assign<ShopHostKitOptions>(o =>
{
o.API.IsEnabled = false;
o.API.Name = "api-test";
});

Split each property into its own assignment argument instead:

OptionsHelper.Assign<ShopHostKitOptions>(
o => o.API.IsEnabled = false,
o => o.API.Name = "api-test"
);

Visual Studio offers a “Split into separate assignments” code fix that performs this conversion for you. See OptionsHelper and Source Generator Behaviors.

  1. Ensure host/resource classes are marked partial.
  2. Ensure exactly one [HostKit] class exists in the compilation.
  3. Ensure resource property names are unique (explicit PropertyName can help).
  4. Ensure each resource uses a compatible base and definition attribute style.
  5. Set explicit Name when inference cannot determine resource name.

Duplicate generated property names (SG0005)

Section titled “Duplicate generated property names (SG0005)”

Use unique PropertyName values:

[ResourceDefinition<ProjectResource>("api", PropertyName = "Api")]
[ResourceDefinition<ProjectResource>("admin", PropertyName = "AdminApi")]

Use valid C# identifiers only (Api, RedisCache, OrderDb, etc.).

Keep one [HostKit] per compilation; split scenarios into separate projects if needed.

Use exactly one style per class:

  • [ResourceDefinition("name")]
  • or [ResourceDefinition<TResource>("name")]

Do not apply both to the same class.

Base-type mismatch by style (SG0014 / SG0015)

Section titled “Base-type mismatch by style (SG0014 / SG0015)”
  • If you use non-generic [ResourceDefinition("name")], declare an explicit compatible base.
  • If you use generic [ResourceDefinition<TResource>("name")], do not declare an explicit base.

Unassigned IResourceBuilder<T> property (SG0017)

Section titled “Unassigned IResourceBuilder<T> property (SG0017)”

Every IResourceBuilder<T> property on a resource kit (nullable or not) must be assigned in either BuildResource or ConfigureResource. CS8618 is automatically suppressed for these properties because they are populated at runtime, so SG0017 is the signal that a property is never set:

[ResourceDefinition<AzureSqlServerResource>("sql")]
sealed partial class SqlServerKit
{
public IResourceBuilder<AzureSqlDatabaseResource> Database { get; private set; }
protected override void ConfigureResource()
{
Database = ResourceBuilder.AddDatabase("changeops-db", "ChangeOps");
base.ConfigureResource();
}
}