@@ -406,15 +406,6 @@ func (fp *flowProvider) callWithRetries(
406406 "agent_type" : optAgentType ,
407407 }))
408408
409- // Check if we are already in a reflector retry cycle to prevent recursion.
410- if isReflectorRetry (ctx ) {
411- logger .Error ("detected reflector recursion attempt, preventing infinite retry loop" )
412- return nil , errors .New ("reflector recursion detected: cannot retry after reflector advice failed" )
413- }
414-
415- // Mark context as being in retry cycle for next invocation (via reflector).
416- ctx = markReflectorRetry (ctx )
417-
418409 ticker := time .NewTicker (delayBetweenRetries )
419410 defer ticker .Stop ()
420411
@@ -699,6 +690,13 @@ func (fp *flowProvider) performReflector(
699690 }
700691 chain = append (chain , reflectorMsg )
701692 if len (result .funcCalls ) == 0 {
693+ // Check if we are already in a reflector retry cycle to prevent infinite recursion.
694+ // This blocks recursive performReflector calls after caller reflector was invoked.
695+ if isReflectorRetry (ctx ) {
696+ logger .Error ("reflector recursion detected: cannot recursively call reflector after caller reflector" )
697+ return nil , errors .New ("reflector recursion detected: LLM returned no tool calls after reflector advice" )
698+ }
699+
702700 return fp .performReflector (ctx , optOriginType , chainID , taskID , subtaskID , chain , executor ,
703701 humanMessage , result .content , executionContext , iteration + 1 )
704702 }
@@ -726,6 +724,21 @@ func (fp *flowProvider) performCallerReflector(
726724 "msg_chain_id" : chainID ,
727725 "errors_count" : len (errs ),
728726 })).WithError (errors .Join (errs ... ))
727+
728+ // Check if we are already in a reflector retry cycle to prevent infinite recursion.
729+ // This blocks repeated calls to performCallerReflector after reflector advice failed.
730+ if isReflectorRetry (ctx ) {
731+ logger .Error ("reflector recursion detected: caller reflector already invoked in this chain" )
732+ return nil , errors .New ("reflector recursion detected: cannot invoke caller reflector again after reflector advice failed" )
733+ }
734+
735+ // Mark context to prevent any further reflector recursion.
736+ // This flag will be checked in:
737+ // 1. performCallerReflector (here) - if reflector advice fails again
738+ // 2. performReflector - before recursive call when no tool calls returned
739+ ctx = markReflectorRetry (ctx )
740+ logger = logger .WithContext (ctx )
741+
729742 logger .Warn ("max retries reached, invoking caller reflector for guidance" )
730743
731744 reflectorContent := fmt .Sprintf (
0 commit comments