@@ -178,9 +178,8 @@ public ParameterValue createValue(StaplerRequest2 request, JSONObject jO) {
178178
179179 @ Override
180180 public ParameterValue createValue (CLICommand command , String value ) throws IOException , InterruptedException {
181- // Clear the allowedValues cache when invoked through CLI.
182- // Cache does not need to be cleared when invoked through
183- // Stapler because generateParamList is called to fill the cache
181+ // Clear the allowedValues cache when invoked through CLI to ensure fresh data.
182+ // The isValid() method will refresh the cache if needed.
184183 allowedValues = null ;
185184 if (isNotEmpty (value )) {
186185 GitParameterValue gitParameterValue = new GitParameterValue (getName (), value );
@@ -679,28 +678,35 @@ public boolean isValid(ParameterValue value) {
679678 return true ; // SECURITY-3419
680679 }
681680 if (value .getValue () instanceof String strValue ) {
682- if (allowedValues == null ) {
683- if (Jenkins .getInstanceOrNull () == null ) {
684- return false ; // Automated tests only, not a running Jenkins instance
685- }
686- Job job = getParentJob (this );
687- if (job == null ) {
688- return false ; // Automated tests with a Jenkins instance
689- }
690- JobWrapper jobWrapper = JobWrapperFactory .createJobWrapper (job );
691- List <GitSCM > scms = getGitSCMs (jobWrapper , getUseRepository ());
692- if (scms == null || scms .isEmpty ()) {
693- return false ;
694- }
695- try {
696- // Populate the allowedValues set
697- allowedValues = generateParamList (jobWrapper , scms ).keySet ();
698- } catch (Exception e ) {
699- LOGGER .log (Level .SEVERE , "Allowed values not generated" , e );
700- return false ;
701- }
681+ // Fast path: check if value exists in cache
682+ if (allowedValues != null && allowedValues .contains (strValue )) {
683+ return true ;
684+ }
685+
686+ // Slow path: refresh cache from git and check again
687+ // This handles two cases:
688+ // 1. Cache is null (never populated)
689+ // 2. Cache is stale (value not found, might be a newly created tag/branch)
690+ if (Jenkins .getInstanceOrNull () == null ) {
691+ return false ; // Automated tests only, not a running Jenkins instance
692+ }
693+ Job job = getParentJob (this );
694+ if (job == null ) {
695+ return false ; // Automated tests with a Jenkins instance
696+ }
697+ JobWrapper jobWrapper = JobWrapperFactory .createJobWrapper (job );
698+ List <GitSCM > scms = getGitSCMs (jobWrapper , getUseRepository ());
699+ if (scms == null || scms .isEmpty ()) {
700+ return false ;
701+ }
702+ try {
703+ // Refresh the allowedValues cache from git
704+ allowedValues = generateParamList (jobWrapper , scms ).keySet ();
705+ return allowedValues .contains (strValue );
706+ } catch (Exception e ) {
707+ LOGGER .log (Level .SEVERE , "Allowed values not generated" , e );
708+ return false ;
702709 }
703- return allowedValues .contains (strValue );
704710 }
705711 return false ;
706712 }
0 commit comments