diff --git a/api/http/handler/tags/tag_delete.go b/api/http/handler/tags/tag_delete.go index 1fa98e394..5e67c4f4c 100644 --- a/api/http/handler/tags/tag_delete.go +++ b/api/http/handler/tags/tag_delete.go @@ -59,6 +59,9 @@ func deleteTag(tx dataservices.DataStoreTx, tagID portainer.TagID) error { for endpointID := range tag.Endpoints { endpoint, err := tx.Endpoint().Endpoint(endpointID) + if tx.IsErrObjectNotFound(err) { + continue + } if err != nil { return httperror.InternalServerError("Unable to retrieve environment from the database", err) } diff --git a/api/http/handler/tags/tag_delete_test.go b/api/http/handler/tags/tag_delete_test.go index cabf20963..a215e7edd 100644 --- a/api/http/handler/tags/tag_delete_test.go +++ b/api/http/handler/tags/tag_delete_test.go @@ -84,3 +84,28 @@ func TestTagDeleteEdgeGroupsConcurrently(t *testing.T) { t.Fatal("the edge group is not consistent") } } + +func TestDeleteTag(t *testing.T) { + _, store := datastore.MustNewTestStore(t, true, false) + + // Test the tx.IsErrObjectNotFound logic when endpoint is not found during cleanup + t.Run("should continue gracefully when endpoint not found during cleanup", func(t *testing.T) { + // Create a tag with a reference to a non-existent endpoint + tag := &portainer.Tag{ + ID: 1, + Name: "test-tag", + Endpoints: map[portainer.EndpointID]bool{999: true}, // Non-existent endpoint + EndpointGroups: make(map[portainer.EndpointGroupID]bool), + } + + err := store.Tag().Create(tag) + if err != nil { + t.Fatal("could not create tag:", err) + } + + err = deleteTag(store, 1) + if err != nil { + t.Fatal("could not delete tag:", err) + } + }) +}