From 51e42d4b11dea0fd85d2366f816da2d79c1357c4 Mon Sep 17 00:00:00 2001 From: water <672684719@qq.com> Date: Sat, 22 Aug 2026 21:55:08 +0800 Subject: [PATCH] fix: drop queued job updates for deleted runs instead of requeueing forever (#39037) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a repository is deleted while one of its Actions runs still has a pending job update in the emitter queue, `checkJobsByRunID` returns an error because the run no longer exists. The queue handler in `jobEmitterQueueHandler` treats every error as unhandled and requeues the item, creating an infinite retry loop that fills the log with error messages. ### Changes 1. **`services/actions/job_emitter.go`** — swap the `!exist`/`err` check order so a database error is reported first, then treat a non-existent run as handled (nil error). The queue consumer drops the item instead of requeueing it. 2. **`services/actions/job_emitter_test.go`** — add `Test_checkJobsByRunID_DeletedRunIsHandled`, which verifies that a deleted run produces nil (handled, not requeued). ### Related issue Fixes #39034 --------- Co-authored-by: bircni --- services/actions/job_emitter.go | 8 +++++--- services/actions/job_emitter_test.go | 8 ++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/services/actions/job_emitter.go b/services/actions/job_emitter.go index 3f93a32d7a1..ca0482ab5a3 100644 --- a/services/actions/job_emitter.go +++ b/services/actions/job_emitter.go @@ -64,12 +64,14 @@ func jobEmitterQueueHandler(items ...*jobUpdate) []*jobUpdate { func checkJobsByRunID(ctx context.Context, runID int64) error { run, exist, err := db.GetByID[actions_model.ActionRun](ctx, runID) - if !exist { - return fmt.Errorf("run %d does not exist", runID) - } if err != nil { return fmt.Errorf("get action run: %w", err) } + if !exist { + // a deleted run never comes back, returning an error here would requeue the update forever + log.Debug("check run %d: run no longer exists, dropping the queued update", runID) + return nil + } var result jobsCheckResult if err := db.WithTx(ctx, func(ctx context.Context) error { // check jobs of the current run diff --git a/services/actions/job_emitter_test.go b/services/actions/job_emitter_test.go index 6458a3e11cb..431ae53c679 100644 --- a/services/actions/job_emitter_test.go +++ b/services/actions/job_emitter_test.go @@ -685,3 +685,11 @@ func Test_jobStatusResolverStopsAfterMatrixInsert(t *testing.T) { "report must wait for the re-emit, which sees the sibling combinations too") }) } + +// https://github.com/go-gitea/gitea/issues/39034 +func Test_jobEmitterQueueHandler_DeletedRunIsNotRequeued(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + + assert.Empty(t, jobEmitterQueueHandler(&jobUpdate{RunID: unittest.NonexistentID}), + "an update for a deleted run must be dropped, not returned as unhandled") +}