Accessing the `KeyValueStoreKernel.KernelSpecifierDirective` property more than once causes an `ArgumentException` due to duplicate parameter registration
Describe the bug
Accessing the [KeyValueStoreKernel.KernelSpecifierDirective] property more than once causes an ArgumentException due to duplicate parameter registration.
Each time the KeyValueStoreKernel.KernelSpecifierDirective getter is called (see KeyValueStoreKernel.cs, line 75), it adds parameters (e.g., --name, --from-url, etc.) to the Parameters collection (a instance of NamedSymbolCollection<KernelDirectiveParameter>) without checking whether those parameters have already been added.
Since the underlying instance of NamedSymbolCollection<KernelDirectiveParameter> enforces uniqueness of parameter names (see KernelDirective.cs, line 25), subsequent accesses to the property throw an ArgumentException:
throw new System.ArgumentException($"Directive already contains a parameter named '{adding.Name}'.");
This bug can be triggered by any logic that accesses the KernelSpecifierDirective property more than once—for example, if the directive is re-registered, re-evaluated, or inspected through introspection APIs.
Which version of .NET Interactive are you using?
This issue affects any build that uses the Microsoft.DotNet.Interactive NuGet package as a dependency and includes commit 5d87547919bad9a6adb3b6745db3fcf0c019530e, which introduced the bug. The issue has not been fixed in any version as of this report.
It does not affect standalone or other usages of .NET Interactive unless they directly depend on and invoke code from the Microsoft.DotNet.Interactive package.
Screenshots
Impact
This is a non-critical bug.
It does not affect normal execution of directives in typical usage scenarios. However, it may impact developer experience, particularly when:
- Directives are programmatically re-evaluated or introspected.
- The
KernelSpecifierDirectiveproperty is accessed multiple times (e.g., in custom tooling or during debugging). - Using reflection, debugger visualizers, or introspection APIs that cause multiple evaluations of directive metadata.
The bug manifests as an ArgumentException during such repeated accesses, which can be confusing or disruptive when diagnosing behavior or extending the package, but does not impact the runtime behavior of well-structured code paths that access the property only once.
Suggested Fix
Ensure that parameters are only added once to the KernelSpecifierDirective.Parameters collection. This can be addressed in one of the following ways:
- Check for existing parameters before adding new ones, to prevent duplicates.
- Recreate a fresh
KernelSpecifierDirectiveinstance each time the property is accessed, ensuring that theParameterscollection always starts empty before parameters are added. - Alternatively, cache and reuse a single instance of the directive (e.g., via a lazy-initialized field). However, this approach should be carefully considered: the base class already uses a private cache field for this property. Introducing a second cache in the derived class would be a design inconsistency, resulting in a property with two distinct caching mechanisms in the inheritance chain—this would be confusing and error-prone.
Given this, recreating a fresh directive each time is likely the cleanest and most reliable fix unless the base class is modified to support reuse through protected or virtual mechanisms.
Can you provide a simple repro, ideally in the form of a failing test, that demonstrates the scenario that this issue is preventing?