@@ -12,6 +12,7 @@ namespace System.CommandLine.Parsing
1212 public sealed class ArgumentResult : SymbolResult
1313 {
1414 private ArgumentConversionResult ? _conversionResult ;
15+ private bool _validatorsHaveBeenRun ;
1516 private bool _onlyTakeHasBeenCalled ;
1617
1718 internal ArgumentResult (
@@ -31,8 +32,27 @@ internal ArgumentResult(
3132
3233 public bool Implicit { get ; private set ; }
3334
34- internal ArgumentConversionResult GetArgumentConversionResult ( ) =>
35- _conversionResult ??= ValidateAndConvert ( useValidators : true ) ;
35+ internal ArgumentConversionResult GetArgumentConversionResult ( )
36+ {
37+ if ( _conversionResult is not null )
38+ {
39+ if ( ! _validatorsHaveBeenRun && Argument . HasValidators )
40+ {
41+ // GetValueOrDefault was called before GetArgumentConversionResult,
42+ // which cached a conversion result without running validators.
43+ // Run them now so that validators like AcceptExistingOnly() are not skipped.
44+ _validatorsHaveBeenRun = true ;
45+ for ( var i = 0 ; i < Argument . Validators . Count ; i ++ )
46+ {
47+ Argument . Validators [ i ] ( this ) ;
48+ }
49+ }
50+
51+ return _conversionResult ;
52+ }
53+
54+ return _conversionResult = ValidateAndConvert ( useValidators : true ) ;
55+ }
3656
3757 /// <summary>
3858 /// Gets the parsed value or the default value for <see cref="Argument"/>.
@@ -141,6 +161,8 @@ private ArgumentConversionResult ValidateAndConvert(bool useValidators)
141161 // => GetValueOrDefault => ValidateAndConvert (again)
142162 if ( useValidators && Argument . HasValidators )
143163 {
164+ _validatorsHaveBeenRun = true ;
165+
144166 for ( var i = 0 ; i < Argument . Validators . Count ; i ++ )
145167 {
146168 Argument . Validators [ i ] ( this ) ;
0 commit comments