Skip to content

Latest commit

 

History

History
476 lines (405 loc) · 25.1 KB

File metadata and controls

476 lines (405 loc) · 25.1 KB

Diagnostics Reference

This document is the stable reference for diagnostic IDs, descriptions, and example scenarios. IDs and anchors are stable; message text is localized.

Errors

DIE000

  • Description: Unable to resolve a dependency in the object graph.
  • Problem: The generator cannot find a binding or auto-binding that satisfies a required injection.
  • Fix: Add a binding for the missing abstraction or enable/allow auto-binding for the concrete type.
  • See: injections-of-abstractions.
  • Examples: A root depends on a service that has no binding.

DIE001

  • Description: Binding cannot be built because its metadata is invalid or incomplete.
  • Problem: A binding is missing required information (type, source, or factory), or implementation-level binding attributes define conflicting metadata.
  • Fix: Ensure the binding has a valid .Bind(...).To<...>() or .Bind(...).To(ctx => ...) chain. For implementation attributes, specify lifetime at most once inside one square-bracket attribute group.
  • See: simplified-binding, bind-metadata-merge.
  • Examples: Binding is incomplete, the setup call is malformed, or [Bind(...), Lifetime(...)] repeats lifetime metadata in the same attribute group.

DIE002

  • Description: Binding is invalid because the compiler reported errors.
  • Problem: The compiler produced errors in code used by the binding.
  • Fix: Fix compilation errors in the referenced type or factory code.
  • See: simplified-binding.
  • Examples: Binding references a type that failed to compile.

DIE003

  • Description: Composition type name is invalid.
  • Problem: The composition name is not a valid C# type name.
  • Fix: Use a valid identifier or fully qualified type name (letters/digits/underscore).
  • See: composition-roots.
  • Examples: DI.Setup("Bad Name!").

DIE004

  • Description: Root name is invalid.
  • Problem: The root property/method name is not a valid identifier.
  • Fix: Use a valid C# identifier without spaces or punctuation.
  • See: composition-roots.
  • Examples: Root<Service>("Bad Name!").

DIE005

  • Description: Duplicate root names detected.
  • Problem: Multiple roots produce the same generated member name.
  • Fix: Rename one of the roots to a unique name.
  • See: composition-roots.
  • Examples: Two roots with the same name.

DIE006

  • Description: Argument name is invalid.
  • Problem: Argument name is not a valid C# identifier.
  • Fix: Use a valid identifier, for example argName or timeoutSeconds.
  • See: composition-arguments.
  • Examples: Arg<int>("bad name").

DIE007

  • Description: Composition argument type is based on a generic marker.
  • Problem: Composition arguments cannot use TT or marker-based types.
  • Fix: Replace marker types with concrete types or proper generic parameters.
  • See: composition-arguments.
  • Examples: Arg<TT>("arg").

DIE008

  • Description: Accumulator type is based on a generic marker.
  • Problem: Accumulators cannot be defined with marker-based types.
  • Fix: Use a concrete accumulator type or a valid generic type.
  • See: accumulators.
  • Examples: Accumulator<TT>().

DIE009

  • Description: Accumulator cannot accumulate a generic marker.
  • Problem: The accumulated element type is marker-based.
  • Fix: Use concrete types or valid generic arguments for accumulated values.
  • See: accumulators.
  • Examples: Accumulator value uses TT.

DIE010

  • Description: Special type cannot be a generic marker.
  • Problem: SpecialType<T> does not accept marker-based types.
  • Fix: Use concrete or supported special types.
  • See: simplified-binding.
  • Examples: SpecialType<IComparer<TT>>().

DIE011

  • Description: Implementation does not implement the contract.
  • Problem: The bound implementation does not satisfy the abstraction.
  • Fix: Bind the correct implementation or change the contract to match.
  • See: injections-of-abstractions.
  • Examples: Bind<IService>().To<Service>() where Service does not implement IService.

DIE012

  • Description: Attribute argument position is invalid.
  • Problem: The attribute argument index does not exist.
  • Fix: Use a valid argument index or adjust the attribute definition.
  • See: custom-attributes.
  • Examples: Attribute argument index is out of range.

DIE013

  • Description: Attribute member cannot be processed.
  • Problem: The attribute usage is ambiguous or conflicting.
  • Fix: Use a single, unambiguous attribute or remove duplicates.
  • See: custom-attributes.
  • Examples: Multiple attributes cause ambiguity.

DIE014

  • Description: Root type is invalid.
  • Problem: Root declaration does not provide a valid type argument.
  • Fix: Use Root<T> with a valid type.
  • See: roots.
  • Examples: Root() without a type argument.

DIE015

  • Description: Roots type is invalid.
  • Problem: The roots API requires a non-object type.
  • Fix: Use a specific service/abstraction type.
  • See: roots.
  • Examples: Roots<object>().

DIE016

  • Description: No type matched the wildcard filter.
  • Problem: The wildcard filter excluded all candidate types.
  • Fix: Adjust the filter or remove it to include matching types.
  • See: roots-with-filter.
  • Examples: Roots<IService>(filter: "NoMatch*").

DIE017

  • Description: Builders type is invalid.
  • Problem: The builders API requires a non-object type.
  • Fix: Use a specific type for builders.
  • See: builders.
  • Examples: Builders<object>().

DIE018

  • Description: Builder type is invalid.
  • Problem: Builder declaration does not provide a valid type argument.
  • Fix: Use Builder<T> with a valid type.
  • See: builder.
  • Examples: Builder() without a type argument.

DIE019

  • Description: Too many type parameters provided.
  • Problem: The API call uses more generic arguments than supported.
  • Fix: Remove extra type arguments or use the correct overload.
  • See: generics.
  • Examples: Invalid generic API usage.

DIE020

  • Description: Async factories are not supported.
  • Problem: async lambdas are not supported in factory bindings.
  • Fix: Use a synchronous factory or wrap async logic outside the composition.
  • See: factory.
  • Examples: .To(async ctx => ...).

DIE021

  • Description: Unsupported syntax in DI API.
  • Problem: The generator encountered an expression it cannot process.
  • Fix: Use supported API patterns (constants, simple expressions, or factories).
  • See: factory.
  • Examples: Unsupported expressions passed into Bind/To/Root.

DIE022

  • Description: Value must be of a specific type.
  • Problem: A constant of the expected type is required.
  • Fix: Provide a constant literal or use a supported API call.
  • See: tags.
  • Examples: Tag or hint expects a constant value.

DIE023

  • Description: Identifier is invalid.
  • Problem: A name used in setup is not a valid identifier.
  • Fix: Use a valid identifier (letters/digits/underscore; no spaces).
  • See: composition-roots.
  • Examples: Root or builder name is not a valid C# identifier.

DIE024

  • Description: Context is used directly where it is not allowed.
  • Problem: ctx is used as a value rather than calling its methods.
  • Fix: Replace direct usage with ctx.Inject(...) or ctx.Override(...).
  • See: factory.
  • Examples: ctx used as a value instead of ctx.Inject(...).

DIE025

  • Description: Initializers count does not match.
  • Problem: Factory initializers do not align with generated markers.
  • Fix: Ensure the factory uses only supported initializer patterns.
  • See: factory.
  • Examples: Factory code does not match initializer markers.

DIE026

  • Description: Lifetime does not support cyclic dependencies.
  • Problem: The dependency graph contains cycles incompatible with the lifetime.
  • Fix: Break the cycle or change lifetimes to compatible ones.
  • See: scope.
  • Examples: Singleton depending on Scoped with cycles.

DIE027

  • Description: Composition is too large to build.
  • Problem: Graph exploration exceeded the maximum iteration limit.
  • Fix: Reduce graph size or adjust limits if supported.
  • See: composition-roots.
  • Examples: Graph iteration limit exceeded.

DIE028

  • Description: Cannot construct an abstract type.
  • Problem: The binding points to an abstract class or interface.
  • Fix: Bind to a concrete implementation type.
  • See: auto-bindings.
  • Examples: Binding to an abstract class.

DIE029

  • Description: No accessible constructor found.
  • Problem: No public/internal constructors are available.
  • Fix: Add an accessible constructor or use a factory binding.
  • See: auto-bindings.
  • Examples: Only private constructors are available.

DIE030

  • Description: Dependency graph cannot be built.
  • Problem: The graph cannot converge to a resolved state.
  • Fix: Check for missing bindings or conflicting lifetimes.
  • See: resolve-methods.
  • Examples: Variational graph resolution failed.

DIE031

  • Description: Maximum number of iterations reached.
  • Problem: Graph building exceeded configured iteration limit.
  • Fix: Simplify the graph or increase the limit.
  • See: composition-roots.
  • Examples: Graph build exceeded max iterations.

DIE032

  • Description: No accessible constructor found for Tag.On.
  • Problem: No constructor matches the Tag.On criteria.
  • Fix: Update the type or the Tag.On arguments to match a constructor.
  • See: tag-on-a-constructor-argument.
  • Examples: Tag.OnConstructorArg<T>(...) with no matching constructor.

DIE033

  • Description: No accessible method found for Tag.On.
  • Problem: No method matches the Tag.On criteria.
  • Fix: Update the type or the Tag.On arguments to match a method.
  • See: tag-on-a-method-argument.
  • Examples: Tag.OnMethodArg<T>(...) with no matching method.

DIE034

  • Description: No accessible field or property found for Tag.On.
  • Problem: No field/property matches the Tag.On criteria.
  • Fix: Update the type or the Tag.On arguments to match a member.
  • See: tag-on-a-member.
  • Examples: Tag.OnMember<T>(...) with no matching member.

DIE035

  • Description: Expression must be a valid API call.
  • Problem: A non-constant or unsupported expression was provided.
  • Fix: Use a constant, a supported API call, or rewrite the expression.
  • See: tags.
  • Examples: Passing a non-constant expression to Tag or Hint.

DIE036

  • Description: Regular expression is invalid.
  • Problem: The regex pattern cannot be parsed.
  • Fix: Fix the regex syntax or escape special characters.
  • See: oncannotresolve-regular-expression-hint.
  • Examples: Invalid regex in a hint filter.

DIE037

  • Description: Wildcard is invalid.
  • Problem: The wildcard pattern is malformed.
  • Fix: Use supported wildcard syntax.
  • See: oncannotresolve-wildcard-hint.
  • Examples: Invalid wildcard pattern in a hint filter.

DIE038

  • Description: DI setup could not be found.
  • Problem: DependsOn refers to a setup that does not exist.
  • Fix: Add the missing setup or correct the name.
  • See: dependent-compositions.
  • Examples: DependsOn("MissingSetup").

DIE039

  • Description: Cyclic dependency detected.
  • Problem: A dependency cycle exists in the graph.
  • Fix: Break the cycle or introduce a factory/Func to defer construction.
  • See: injection-on-demand.
  • Examples: A -> B -> A.

DIE040

  • Description: Language version is not supported.
  • Problem: The project uses a C# version below the required minimum.
  • Fix: Increase the language version in project settings.
  • See: composition-roots.
  • Examples: Using C# language version below the minimum.

DIE041

  • Description: Lifetime validation error.
  • Problem: A root/lifetime combination is not allowed.
  • Fix: Change lifetimes or root kind to a compatible configuration.
  • See: static-root.
  • Examples: Static root depends on Scoped/Singleton in unsupported way.

DIE042

  • Description: Type cannot be inferred.
  • Problem: The generator cannot determine the type from the expression.
  • Fix: Specify the type explicitly (generic argument or cast).
  • See: overrides.
  • Examples: Override(...) without an inferable type.

DIE043

  • Description: Unhandled generator error.
  • Problem: An unexpected exception occurred in the generator.
  • Fix: Reduce the scenario and report a bug with repro steps.
  • See: check-for-a-root.

DIE044

  • Description: DependsOn requires a setup context name when using a setup context kind (except Members).
  • Problem: DependsOn was called with a setup context kind but without a context name.
  • Fix: Provide a non-empty name value or use DependsOn(params string[] setupNames) when a context is not needed. SetupContextKind.Members allows omitting name.
  • Examples: DependsOn(setupName, contextKind) without providing name parameter.

DIE046

  • Description: Cannot use stack-only dependency with stored lifetime.
  • Problem: Stored lifetimes such as Singleton, Scoped, and PerResolve may keep instances beyond the current stack frame. This also applies to generic T with where T : allows ref struct.
  • Fix: Keep stack-only values transient and consume them immediately through method injection.
  • See: span-and-readonlyspan.
  • Examples: Bind().As(Lifetime.Singleton).To<Parser>() where Parser needs ReadOnlySpan<char>.

DIE047

  • Description: Cannot inject stack-only dependency into field or property.
  • Problem: Field and property injection may expose a scoped Span<T>, ReadOnlySpan<T>, custom ref struct, or generic T with where T : allows ref struct root argument outside its declaration scope. Even a setter-only property is opaque to the compiler at the call site.
  • Fix: Replace the field/property injection with method injection that consumes the stack-only value immediately.
  • See: span-and-readonlyspan.
  • Examples: [Ordinal] public ReadOnlySpan<char> Text;, [Ordinal] public ReadOnlySpan<char> Text { set { ... } }, or public ReadOnlySpan<char> Text { get; init; }.

DIE048

  • Description: Cannot inject stack-only implementation through an interface conversion.
  • Problem: Converting a ref struct implementation to an interface requires an interface conversion path that is not valid for stack-only values. This also applies to generic implementations such as Parser<T> when the implementation itself is a ref struct.
  • Fix: Use the concrete stack-only type directly in an immediate method call, or replace it with a heap-safe class/adapter. Generic interfaces such as IParser<T> are allowed when the implementation is heap-safe, for example class Parser<T> : IParser<T>.
  • See: span-and-readonlyspan.
  • Examples: Bind<IParser>().To<Parser>() where Parser is a ref struct, or Bind<IParser<T>>().To<Parser<T>>() where Parser<T> is a ref struct.

DIE049

  • Description: Cannot capture stack-only dependency in a generated delegate or factory.
  • Problem: A generated delegate or deferred factory can outlive the current stack frame. Capturing Span<T>, ReadOnlySpan<T>, a custom ref struct, or generic T with where T : allows ref struct would allow a stack-only value to escape.
  • Fix: Resolve and consume the stack-only value immediately in a root method, immediate factory body, or the current delegate invocation. Delegate arguments such as T text may be passed through ctx.Override<T>(text)/ctx.Let<T>(text) only when the target consumes them immediately; do not pass them into nested or returned delegates.
  • See: span-and-readonlyspan.
  • Examples: Bind<ParserAction<T>>().To(ctx => new ParserAction<T>(() => ctx.Inject<T>(out _))) where T : allows ref struct, a delegate argument routed into field/property injection, or text captured by a nested Action.

DIE050

  • Description: Several case bindings can be implicitly converted to the union contract.
  • Problem: A union contract (for example union PaymentGateway(StripeGateway, BankGateway);) is requested without an exact union binding, and more than one registered binding can be implicitly converted to that union with the same tag. Pure.DI cannot arbitrarily pick one case before compilation. The diagnostic lists each candidate's case type, lifetime, and binding expression, and adds the candidate binding locations as related locations.
  • Fix: Bind the union contract explicitly (Bind<PaymentGateway>().To<StripeGateway>()), use distinct tags for the case bindings and tagged injections/roots, or remove one of the candidate bindings.
  • Examples: Bind<StripeGateway>().To<StripeGateway>() and Bind<BankGateway>().To<BankGateway>() combined with Root<PaymentGateway>("Gateway").

Warnings

DIW000

  • Description: Binding has been overridden.
  • Problem: A later binding replaces an earlier one for the same contract/tag.
  • Fix: Remove the earlier binding or add tags to distinguish them.
  • See: overriding-the-bcl-binding.
  • Examples: Two bindings for the same contract/tag, the latter wins.

DIW001

  • Description: No composition roots defined.
  • Problem: The composition exposes no roots.
  • Fix: Add at least one .Root(...) declaration.
  • See: composition-roots.
  • Examples: DI.Setup("Composition") without any .Root(...).

DIW002

  • Description: Implementation does not implement the contract.
  • Problem: The implementation does not satisfy the requested contract.
  • Fix: Use a correct implementation or adjust the contract.
  • See: injections-of-abstractions.
  • Examples: Severity is Warning for not implemented contract.

DIW003

  • Description: Binding is not used.
  • Problem: The binding is never requested by any root.
  • Fix: Remove unused bindings or reference them in a root.
  • See: composition-roots.
  • Examples: Binding has no consumers in the graph.

DIW004

  • Description: Tag.On injection site is not used.
  • Problem: The tag-on site is never matched by any injection.
  • Fix: Update the Tag.On expression or add matching injections.
  • See: tag-on-injection-site.
  • Examples: Tag.On(...) not referenced by any injection.

DIW005

  • Description: Resolve methods are incompatible with root arguments.
  • Problem: Resolve cannot provide values for root arguments.
  • Fix: Disable Resolve methods or remove RootArg usage.
  • See: resolve-methods.
  • Examples: Root uses RootArg but Resolve is enabled.

DIW006

  • Description: Resolve methods are incompatible with type arguments.
  • Problem: Resolve cannot supply generic type arguments.
  • Fix: Use explicit roots or avoid Resolve for generic roots.
  • See: resolve-methods.
  • Examples: Generic roots with Resolve methods.

DIW007

  • Description: DependsOn uses an instance member.
  • Problem: A binding in a dependent setup references an instance member that will not exist in the dependent composition.
  • Fix: Use .DependsOn(setupName, contextArgName) to pass an explicit setup context, or move the value to Arg/RootArg or a separate context object.
  • See: dependent-compositions.
  • Examples: Binding in a dependent setup uses instance field/property.

DIW008

  • Description: GenerateInterface is applied to a non-public element.
  • Problem: [GenerateInterface] was placed on a non-public method/property/event.
  • Fix: Make the element public or remove the attribute from that element.
  • See: generate-interface.
  • Examples: [GenerateInterface] on private or internal property.

DIW009

  • Description: GenerateInterface is applied to a static element.
  • Problem: [GenerateInterface] was placed on a static method/property/event.
  • Fix: Move the contract element to an instance member or remove the attribute.
  • See: generate-interface.
  • Examples: [GenerateInterface] on public static method.

DIW010

  • Description: Selective interface generation produced an empty interface.
  • Problem: Selective mode was enabled for an interface, but no eligible elements remained after filtering.
  • Fix: Mark at least one public instance element for that interface, or remove selective member annotations.
  • See: generate-interface.
  • Examples: All selected elements are IgnoreInterface, non-public, or static.

DIW011

  • Description: Resolve(Type) cannot distinguish nullable and non-nullable roots.
  • Problem: Two roots have the same runtime type but different nullable reference annotations, for example IService and IService?. Resolve(Type) and Resolve(Type, tag) receive only System.Type, so nullable reference annotations are not available at runtime.
  • Fix: Use Resolve<T>(), remove one of the runtime-equivalent roots, or disable Resolve methods when runtime resolution is not needed.
  • See: resolve-methods, nullable-reference-types.
  • Examples: Root<IService>("Service") and Root<IService?>("NullableService") while Resolve methods are enabled.

DIW012

  • Description: Stack-only dependency is injected into constructor of heap type.
  • Problem: Constructor injection may be valid when the constructor consumes Span<T>, ReadOnlySpan<T>, a custom ref struct, or generic T with where T : allows ref struct immediately, but it is easy to accidentally store stack-only state in a heap object.
  • Fix: Prefer method injection with a scoped root argument for new code when the stack-only value is only needed during initialization.
  • See: span-and-readonlyspan.
  • Examples: class Parser(ReadOnlySpan<char> text) resolved by a composition root.

DIW013

  • Description: Stack-only override in a factory delegate should be synchronized.
  • Problem: A manual factory delegate can be invoked concurrently. Using ctx.Override<T>(...) or ctx.Let<T>(...) with Span<T>, ReadOnlySpan<T>, a custom ref struct, or generic T with where T : allows ref struct without lock (ctx.Lock) can mix override values between parallel invocations.
  • Fix: Wrap the override and the following ctx.Inject(...)/ctx.BuildUp(...) in lock (ctx.Lock), or explicitly disable thread safety when the composition is known to be single-threaded.
  • See: thread-safe-overrides, span-and-readonlyspan, default-func-with-readonlyspan.
  • Examples: new ParserFactory<T>(text => { ctx.Override<T>(text); ctx.Inject<Parser<T>>(out var parser); return parser; }) where T : allows ref struct. The generated default Func<ReadOnlySpan<char>, T> binding is different: it uses local values in the generated delegate invocation and does not require a manual lock.

DIW014

  • Description: An injection method may resolve to another overload with a higher OverloadResolutionPriority.
  • Problem: Pure.DI emits a regular C# method call for method injection. When another applicable overload has a higher OverloadResolutionPriority, the compiler can call that overload instead of the method selected as the injection target.
  • Fix: Give the intended injection overload the highest priority, use a unique method name, or remove the conflicting OverloadResolutionPriorityAttribute.
  • See: overload-resolution-priority, member-ordinal-attribute.
  • Examples: [Ordinal] void Initialize(SpecialDependency dependency) conflicts with [OverloadResolutionPriority(1)] void Initialize(Dependency dependency) when SpecialDependency derives from Dependency.

Info

DII000

  • Description: Generation was interrupted.
  • Problem: Generation aborted early due to a handled exception.
  • Fix: Inspect preceding errors for the root cause.
  • See: check-for-a-root.
  • Examples: Generation aborted due to a handled exception.

DII001

  • Description: Implementation does not implement the contract.
  • Problem: The implementation does not satisfy the requested contract.
  • Fix: Use a correct implementation or adjust the contract.
  • See: injections-of-abstractions.
  • Examples: Severity is Info for not implemented contract.