@@ -246,7 +246,7 @@ func (bm *BasicModule) RegisterHooks(logger *log.Logger) ([]*hooks.ModuleHook, e
246246 return nil , nil
247247 }
248248
249- hks , err := bm .searchModuleHooks ()
249+ hks , hasReadiness , err := bm .searchModuleHooks ()
250250 if err != nil {
251251 return nil , fmt .Errorf ("search module hooks failed: %w" , err )
252252 }
@@ -267,33 +267,27 @@ func (bm *BasicModule) RegisterHooks(logger *log.Logger) ([]*hooks.ModuleHook, e
267267 }
268268
269269 bm .hooks .registered = true
270+ bm .hasReadiness = hasReadiness
270271
271272 return hks , nil
272273}
273274
274- func (bm * BasicModule ) searchModuleHooks () ([]* hooks.ModuleHook , error ) {
275+ func (bm * BasicModule ) searchModuleHooks () ([]* hooks.ModuleHook , bool , error ) {
275276 shellHooks , err := bm .searchModuleShellHooks ()
276277 if err != nil {
277- return nil , fmt .Errorf ("search module shell hooks: %w" , err )
278+ return nil , false , fmt .Errorf ("search module shell hooks: %w" , err )
278279 }
279280
280281 goHooks := bm .searchModuleGoHooks ()
281282
282- batchHooks , err := bm .searchModuleBatchHooks ()
283+ batchHooks , hasReadiness , err := bm .searchModuleBatchHooks ()
283284 if err != nil {
284- return nil , fmt .Errorf ("search module batch hooks: %w" , err )
285- }
286-
287- // TEMPORARY: Simulate error after hasReadiness is set to reproduce the bug.
288- // Set SIMULATE_READINESS_BUG=<module_name> to trigger error for specific module.
289- // After first error, hasReadiness stays true, causing "multiple readiness hooks found" on retry.
290- if simulateModule := os .Getenv ("SIMULATE_READINESS_BUG" ); simulateModule != "" && bm .Name == simulateModule && bm .hasReadiness {
291- return nil , fmt .Errorf ("SIMULATED ERROR: testing hasReadiness bug for module %s" , bm .Name )
285+ return nil , false , fmt .Errorf ("search module batch hooks: %w" , err )
292286 }
293287
294288 if len (shellHooks )+ len (batchHooks ) > 0 {
295289 if err := bm .AssembleEnvironmentForModule (environmentmanager .ShellHookEnvironment ); err != nil {
296- return nil , fmt .Errorf ("Assemble %q module's environment: %w" , bm .GetName (), err )
290+ return nil , false , fmt .Errorf ("Assemble %q module's environment: %w" , bm .GetName (), err )
297291 }
298292 }
299293
@@ -318,7 +312,7 @@ func (bm *BasicModule) searchModuleHooks() ([]*hooks.ModuleHook, error) {
318312 return mHooks [i ].GetPath () < mHooks [j ].GetPath ()
319313 })
320314
321- return mHooks , nil
315+ return mHooks , hasReadiness , nil
322316}
323317
324318func (bm * BasicModule ) searchModuleShellHooks () ([]* kind.ShellHook , error ) {
@@ -380,25 +374,22 @@ func (bm *BasicModule) searchModuleShellHooks() ([]*kind.ShellHook, error) {
380374 return hks , nil
381375}
382376
383- func (bm * BasicModule ) searchModuleBatchHooks () ([]* kind.BatchHook , error ) {
384- // FIX DISABLED FOR TESTING:
385- // Reset hasReadiness to handle retries after errors.
386- // If a previous search set hasReadiness=true but failed later (e.g., in AssembleEnvironmentForModule),
387- // hooks.registered remains false but hasReadiness stays true, causing "multiple readiness hooks found"
388- // error on retry.
389- // bm.hasReadiness = false
390-
377+ // searchModuleBatchHooks searches for batch hooks and returns them along with hasReadiness flag.
378+ // This function has no side effects - it doesn't modify bm.hasReadiness directly.
379+ // The caller (RegisterHooks) is responsible for setting bm.hasReadiness after successful registration.
380+ func (bm * BasicModule ) searchModuleBatchHooks () ([]* kind.BatchHook , bool , error ) {
391381 hooksDir := filepath .Join (bm .Path , "hooks" )
392382 if _ , err := os .Stat (hooksDir ); os .IsNotExist (err ) {
393- return nil , nil
383+ return nil , false , nil
394384 }
395385
396386 hooksRelativePaths , err := RecursiveGetBatchHookExecutablePaths (bm .safeName (), hooksDir , bm .logger , hooksExcludedDir ... )
397387 if err != nil {
398- return nil , err
388+ return nil , false , err
399389 }
400390
401391 hks := make ([]* kind.BatchHook , 0 )
392+ hasReadiness := false
402393
403394 // sort hooks by path
404395 sort .Strings (hooksRelativePaths )
@@ -407,20 +398,20 @@ func (bm *BasicModule) searchModuleBatchHooks() ([]*kind.BatchHook, error) {
407398 for _ , hookPath := range hooksRelativePaths {
408399 hookName , err := normalizeHookPath (filepath .Dir (bm .Path ), hookPath )
409400 if err != nil {
410- return nil , fmt .Errorf ("could not get hook name: %w" , err )
401+ return nil , false , fmt .Errorf ("could not get hook name: %w" , err )
411402 }
412403
413404 sdkcfgs , err := kind .GetBatchHookConfig (bm .safeName (), hookPath )
414405 if err != nil {
415- return nil , fmt .Errorf ("getting sdk config for '%s': %w" , hookName , err )
406+ return nil , false , fmt .Errorf ("getting sdk config for '%s': %w" , hookName , err )
416407 }
417408
418409 if sdkcfgs .Readiness != nil {
419- if bm . hasReadiness {
420- return nil , fmt .Errorf ("multiple readiness hooks found in %s" , hookPath )
410+ if hasReadiness {
411+ return nil , false , fmt .Errorf ("multiple readiness hooks found in %s" , hookPath )
421412 }
422413
423- bm . hasReadiness = true
414+ hasReadiness = true
424415
425416 // add readiness hook
426417 nestedHookName := fmt .Sprintf ("%s-readiness" , hookName )
@@ -436,7 +427,7 @@ func (bm *BasicModule) searchModuleBatchHooks() ([]*kind.BatchHook, error) {
436427 }
437428 }
438429
439- return hks , nil
430+ return hks , hasReadiness , nil
440431}
441432
442433func RecursiveGetBatchHookExecutablePaths (moduleName , dir string , logger * log.Logger , excludedDirs ... string ) ([]string , error ) {
0 commit comments