summaryrefslogtreecommitdiff
path: root/internal/api/server_test.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-03-08 21:45:11 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-03-08 21:45:11 +0000
commita6926b80283bbe855bb617be0dbdbaa9968f62f8 (patch)
tree4b1e9b1d8c21d039e2743214d9a79981e29d5b16 /internal/api/server_test.go
parente6e1e7cd6d79eb969345e738f2554108681ade95 (diff)
fix: retry limits apply only to automatic retries, not manual runs
Remove the MaxAttempts check from POST /api/tasks/{id}/run. A user explicitly triggering a run is a manual action and should not be gated by the retry limit. Retry limits will be enforced in the (future) automatic retry path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/api/server_test.go')
-rw-r--r--internal/api/server_test.go28
1 files changed, 12 insertions, 16 deletions
diff --git a/internal/api/server_test.go b/internal/api/server_test.go
index cd415ae..8484e02 100644
--- a/internal/api/server_test.go
+++ b/internal/api/server_test.go
@@ -604,14 +604,14 @@ func TestResumeTimedOut_Success_Returns202(t *testing.T) {
}
}
-func TestRunTask_RetryLimitReached_Returns409(t *testing.T) {
+// TestRunTask_ManualRunIgnoresRetryLimit verifies that a manual POST /run always
+// succeeds regardless of MaxAttempts — retry limits only gate automatic retries.
+func TestRunTask_ManualRunIgnoresRetryLimit(t *testing.T) {
srv, store := testServer(t)
- // Task with MaxAttempts: 1 — only 1 attempt allowed. Create directly as FAILED
- // so state is consistent without going through transition sequence.
tk := &task.Task{
- ID: "retry-limit-1",
+ ID: "retry-limit-manual",
Name: "Retry Limit Task",
- Agent: task.AgentConfig{Instructions: "do something"},
+ Agent: task.AgentConfig{Instructions: "do something"},
Priority: task.PriorityNormal,
Retry: task.RetryConfig{MaxAttempts: 1, Backoff: "linear"},
Tags: []string{},
@@ -621,10 +621,10 @@ func TestRunTask_RetryLimitReached_Returns409(t *testing.T) {
if err := store.CreateTask(tk); err != nil {
t.Fatal(err)
}
- // Record one execution — the first attempt already used.
+ // Record one execution — MaxAttempts already exhausted.
exec := &storage.Execution{
- ID: "exec-retry-1",
- TaskID: "retry-limit-1",
+ ID: "exec-retry-manual",
+ TaskID: "retry-limit-manual",
StartTime: time.Now(),
Status: "FAILED",
}
@@ -632,17 +632,13 @@ func TestRunTask_RetryLimitReached_Returns409(t *testing.T) {
t.Fatal(err)
}
- req := httptest.NewRequest("POST", "/api/tasks/retry-limit-1/run", nil)
+ req := httptest.NewRequest("POST", "/api/tasks/retry-limit-manual/run", nil)
w := httptest.NewRecorder()
srv.Handler().ServeHTTP(w, req)
- if w.Code != http.StatusConflict {
- t.Errorf("status: want 409, got %d; body: %s", w.Code, w.Body.String())
- }
- var body map[string]string
- json.NewDecoder(w.Body).Decode(&body)
- if !strings.Contains(body["error"], "retry limit") {
- t.Errorf("error body should mention retry limit, got %q", body["error"])
+ // Manual run must succeed (202) even though MaxAttempts is exhausted.
+ if w.Code != http.StatusAccepted {
+ t.Errorf("status: want 202, got %d; body: %s", w.Code, w.Body.String())
}
}