Repository: getgauge/gauge (2026-03-30T08:37:16Z)

Issue:
--failed performs retry for passed tests with --max-retry-count flag
When max-retry-count is enabled and after that a gauge run --failed is performed, specs that passed with --max-retry-count will be executed anyway as if they failed.

**To Reproduce**
1. Perform an execution with max-retry-count=2
2. Some tests will pass after 1 retry
3. Perform gauge run --failed
4. Failed tests and those who passed with max-retry-count=2 will execute

**Expected behavior**
I would expect that only tests that completely failed would be triggered by --failed


Your Environment Information -----------
	linux, 1.4.1, a82478a
	html-report (4.1.2), java (0.7.9), json-report (0.3.1), spectacle (0.1.4), xml-report (0.2.3)



Discussion:

Patch:
diff --git a/execution/rerun/rerun.go b/execution/rerun/rerun.go
index 9ac172589..a8aff4ba8 100644
--- a/execution/rerun/rerun.go
+++ b/execution/rerun/rerun.go
@@ -70,6 +70,16 @@ func (m *failedMetadata) addFailedItem(itemName string, item string) {
 	m.failedItemsMap[itemName][item] = true
 }
 
+func (m *failedMetadata) removeFailedItem(itemName string, item string) {
+	if _, ok := m.failedItemsMap[itemName]; !ok {
+		return
+	}
+	delete(m.failedItemsMap[itemName], item)
+	if len(m.failedItemsMap[itemName]) == 0 {
+		delete(m.failedItemsMap, itemName)
+	}
+}
+
 // ListenFailedScenarios listens to execution events and writes the failed scenarios to JSON file
 func ListenFailedScenarios(wg *sync.WaitGroup, specDirs []string) {
 	ch := make(chan event.ExecutionEvent)
@@ -97,11 +107,16 @@ func ListenFailedScenarios(wg *sync.WaitGroup, specDirs []string) {
 }
 
 func prepareScenarioFailedMetadata(res *result.ScenarioResult, sce *gauge.Scenario, executionInfo *gauge_messages.ExecutionInfo) {
+	specPath := executionInfo.GetCurrentSpec().GetFileName()
+	failedScenario := util.RelPathToProjectRoot(specPath)
+	scenarioRef := fmt.Sprintf("%s:%v", failedScenario, sce.Span.Start)
 	if res.GetFailed() {
-		specPath := executionInfo.GetCurrentSpec().GetFileName()
-		failedScenario := util.RelPathToProjectRoot(specPath)
-		failedMeta.addFailedItem(specPath, fmt.Sprintf("%s:%v", failedScenario, sce.Span.Start))
+		failedMeta.addFailedItem(specPath, scenarioRef)
+		return
 	}
+	// A scenario can emit multiple ScenarioEnd events when retries are enabled.
+	// If a later retry passes, remove any failed entry captured from earlier attempts.
+	failedMeta.removeFailedItem(specPath, scenarioRef)
 }
 
 func addSpecFailedMetadata(res result.Result, args []string) {
diff --git a/version/version.go b/version/version.go
index 011cd9d34..205f2abc0 100644
--- a/version/version.go
+++ b/version/version.go
@@ -14,7 +14,7 @@ import (
 )
 
 // CurrentGaugeVersion represents the current version of Gauge
-var CurrentGaugeVersion = &Version{1, 6, 28}
+var CurrentGaugeVersion = &Version{1, 6, 29}
 
 // BuildMetadata represents build information of current release (e.g, nightly build information)
 var BuildMetadata = ""


Test patch:
diff --git a/execution/rerun/rerun_test.go b/execution/rerun/rerun_test.go
index 922f25cf2..f8c9d3f23 100644
--- a/execution/rerun/rerun_test.go
+++ b/execution/rerun/rerun_test.go
@@ -62,6 +62,22 @@ func (s *MySuite) TestGetScenarioFailedMetadata(c *C) {
 	c.Assert(failedMeta.failedItemsMap[spec1Abs][spec1Rel+":2"], Equals, true)
 }
 
+func (s *MySuite) TestScenarioPassingOnRetryRemovesFailedMetadata(c *C) {
+	spec1Rel := filepath.Join("specs", "example1.spec")
+	spec1Abs := filepath.Join(config.ProjectRoot, spec1Rel)
+	sce := &gauge.Scenario{Span: &gauge.Span{Start: 2}}
+	execInfo := &gauge_messages.ExecutionInfo{CurrentSpec: &gauge_messages.SpecInfo{FileName: spec1Abs}}
+	failedResult := &result.ScenarioResult{ProtoScenario: &gauge_messages.ProtoScenario{ExecutionStatus: gauge_messages.ExecutionStatus_FAILED}}
+	passedResult := &result.ScenarioResult{ProtoScenario: &gauge_messages.ProtoScenario{ExecutionStatus: gauge_messages.ExecutionStatus_PASSED}}
+
+	prepareScenarioFailedMetadata(failedResult, sce, execInfo)
+	c.Assert(failedMeta.failedItemsMap[spec1Abs][spec1Rel+":2"], Equals, true)
+
+	prepareScenarioFailedMetadata(passedResult, sce, execInfo)
+	_, exists := failedMeta.failedItemsMap[spec1Abs]
+	c.Assert(exists, Equals, false)
+}
+
 func (s *MySuite) TestAddSpecPreHookFailedMetadata(c *C) {
 	spec1Rel := filepath.Join("specs", "example1.spec")
 	spec1Abs := filepath.Join(config.ProjectRoot, spec1Rel)