Gorse version
master (HEAD b7e6aa9, 2026-04-16). The relevant code lives at common/monitor/progress.go:138-169, introduced in #1208.
Describe the bug
After #1208 removed the divide-by-zero panic, the "zero-total child is complete" fallback can push parentCount above parentTotal when:
- the parent has already consumed its own
count (s.count == s.total), and
- a running child is reporting
Total == 0.
With a parent total=2, count=2 and one running zero-total child:
childTotal (max, fallback) = 1
parentTotal = s.total * childTotal = 2
parentCount = s.count * childTotal = 2
+ childTotal (zero-total child branch) = 3
-> Progress{Count: 3, Total: 2} // 150%
The dashboard progress bar (/api/dashboard/tasks) consumes this value directly and renders >100%.
To Reproduce
// common/monitor/progress_overflow_test.go
package monitor
import (
"context"
"testing"
)
func TestProgress_ZeroTotalChildExceeds100Percent(t *testing.T) {
_, parent := Start(context.Background(), "parent", 2)
parent.Add(2)
ctx := context.WithValue(context.Background(), spanKeyName, parent)
_, _ = Start(ctx, "child", 0)
got := parent.Progress()
t.Logf("parent.Progress() -> Count=%d Total=%d", got.Count, got.Total)
if got.Count > got.Total {
t.Fatalf("Count (%d) exceeds Total (%d)", got.Count, got.Total)
}
}
go test -run TestProgress_ZeroTotal -v ./common/monitor/... fails on HEAD with Count (3) exceeds Total (2).
Expected behavior
Progress.Count <= Progress.Total for every combination of parent/child totals.
Additional context / suggested fix
A one-line clamp before returning:
if parentCount > parentTotal {
parentCount = parentTotal
}
return Progress{..., Count: parentCount, Total: parentTotal, ...}
PR with the clamp + regression test is being opened against this issue.
Gorse version
master(HEADb7e6aa9, 2026-04-16). The relevant code lives atcommon/monitor/progress.go:138-169, introduced in #1208.Describe the bug
After #1208 removed the divide-by-zero panic, the "zero-total child is complete" fallback can push
parentCountaboveparentTotalwhen:count(s.count == s.total), andTotal == 0.With a parent
total=2, count=2and one running zero-total child:The dashboard progress bar (
/api/dashboard/tasks) consumes this value directly and renders>100%.To Reproduce
go test -run TestProgress_ZeroTotal -v ./common/monitor/...fails on HEAD withCount (3) exceeds Total (2).Expected behavior
Progress.Count <= Progress.Totalfor every combination of parent/child totals.Additional context / suggested fix
A one-line clamp before returning:
PR with the clamp + regression test is being opened against this issue.