dotnet / dotnet/command-line-api

[Bug] Type System.String cannot be created without a custom binder.

Open
#1,872 7 comments 0 reactions 0 assignees View on GitHub
Area-NamingConventionBinder bug
Dominant language
C#
Stars
3.7k
Forks
428
PR merge metrics
No merged PRs in 30d

Description

Hello,
on version `2.0.0-beta4.22272.1` I'm getting a consistent `System.ArgumentException:` exception.
Please find a minimal working example below:

```xml


Exe
net6.0
enable
enable




```

```cs
using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.NamingConventionBinder;
using System.CommandLine.Parsing;

RootCommand rootCommand = new()
{
new TestCommand(),
};

Parser parser = new CommandLineBuilder(rootCommand).UseDefaults().Build();
return parser.Invoke(args);

internal class TestCommand : Command
{
public TestCommand() : base("test", "")
{
AddArgument(new Argument("path", "Input path."));

AddOption(new Option(new[] { "--outpath", "-o" }, "Output path."));

Handler = CommandHandler.Create(Action);
}
private int Action(FileSystemInfo[] path, DirectoryInfo outpath)
{
Console.WriteLine("testing");
return 0;
}
}
```
Exception:
```txt
Unhandled exception: System.ArgumentException: Type System.String cannot be created without a custom binder.
at System.CommandLine.Binding.ArgumentConverter.CreateEnumerable(Type type, Type itemType, Int32 capacity)
at System.CommandLine.Binding.ArgumentConverter.ConvertTokens(Argument argument, Type type, IReadOnlyList`1 tokens, LocalizationResources localizationResources, ArgumentResult argumentResult)
at System.CommandLine.Binding.ArgumentConverter.ConvertObject(Argument argument, Type type, Object value, LocalizationResources localizationResources)
at System.CommandLine.Binding.BindingContext.TryBindToScalarValue(IValueDescriptor valueDescriptor, IValueSource valueSource, LocalizationResources localizationResources, Nullable`1& boundValue)
at System.CommandLine.NamingConventionBinder.ModelBinder.GetBoundValue(IValueSource valueSource, BindingContext bindingContext, IValueDescriptor valueDescriptor, Boolean includeMissingValues, Type parentType)
at System.CommandLine.NamingConventionBinder.ModelBinder.GetBoundValues(IDictionary`2 bindingSources, BindingContext bindingContext, IReadOnlyList`1 valueDescriptors, Boolean enforceExplicitBinding, Type parentType, Boolean includeMissingValues)
at System.CommandLine.NamingConventionBinder.ModelBinder.GetBestConstructorAndArgs(BindingContext bindingContext)
at System.CommandLine.NamingConventionBinder.ModelBinder.CreateInstanceInternal(BindingContext bindingContext)
at System.CommandLine.NamingConventionBinder.ModelBinder.GetBoundValue(IValueSource valueSource, BindingContext bindingContext, IValueDescriptor valueDescriptor, Boolean includeMissingValues, Type parentType)
at System.CommandLine.NamingConventionBinder.ModelBinder.GetBoundValues(IDictionary`2 bindingSources, BindingContext bindingContext, IReadOnlyList`1 valueDescriptors, Boolean enforceExplicitBinding, Type parentType, Boolean includeMissingValues)
at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
at System.CommandLine.NamingConventionBinder.ModelBindingCommandHandler.Invoke(InvocationContext context)
at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass17_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass12_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass19_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<b__18_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass16_0.<b__0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<b__5_0>d.MoveNext()
--- End of stack trace from previous location ---
at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass8_0.<b__0>d.MoveNext()```

Contributor guide

Open the contributing guide

Research direction

Reproduce the minimal .NET 6 example with System.CommandLine 2.0.0-beta4.22272.1 and inspect the binding path shown in the trace, especially ArgumentConverter.CreateEnumerable and ModelBinder. Verify that FileSystemInfo[] arguments and DirectoryInfo options bind without a custom binder; done means the example invokes successfully without the System.String exception.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.