From fd9ec495bdeb80760daf93cd5bb1efa1d3d40e87 Mon Sep 17 00:00:00 2001 From: Samuele Verzi Date: Tue, 21 Apr 2026 11:09:05 +0200 Subject: [PATCH 1/2] Return 502 Bad Gateway when OCI content pull fails getContentFromOCI previously mapped registry.Pull failures to 400 Bad Request, but auth errors, unreachable registries, missing manifests, and network timeouts are upstream failures the caller cannot fix by changing their input. Align with getContentFromGit, which already returns 502 Bad Gateway for git resolve failures, so clients see consistent semantics across both backends. --- pkg/skills/skillsvc/content.go | 2 +- pkg/skills/skillsvc/content_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pkg/skills/skillsvc/content.go b/pkg/skills/skillsvc/content.go index 06f0c64e28..507cf6a13d 100644 --- a/pkg/skills/skillsvc/content.go +++ b/pkg/skills/skillsvc/content.go @@ -170,7 +170,7 @@ func (s *service) getContentFromOCI(ctx context.Context, ref string) (*skills.Sk if pullErr != nil { return nil, httperr.WithCode( fmt.Errorf("pulling OCI artifact %q: %w", qualifiedRef, pullErr), - http.StatusBadRequest, + http.StatusBadGateway, ) } } diff --git a/pkg/skills/skillsvc/content_test.go b/pkg/skills/skillsvc/content_test.go index c68406424e..2ee52b512a 100644 --- a/pkg/skills/skillsvc/content_test.go +++ b/pkg/skills/skillsvc/content_test.go @@ -125,7 +125,7 @@ func TestGetContent(t *testing.T) { assert.Equal(t, http.StatusBadRequest, httperr.Code(err)) }) - t.Run("pull failure propagates as 400", func(t *testing.T) { + t.Run("pull failure propagates as 502", func(t *testing.T) { t.Parallel() ctrl := gomock.NewController(t) @@ -142,7 +142,7 @@ func TestGetContent(t *testing.T) { ) _, err = svc.GetContent(t.Context(), skills.ContentOptions{Reference: "ghcr.io/org/my-skill:v1"}) require.Error(t, err) - assert.Equal(t, http.StatusBadRequest, httperr.Code(err)) + assert.Equal(t, http.StatusBadGateway, httperr.Code(err)) assert.Contains(t, err.Error(), "registry unreachable") }) From 8e2660af7fc4d2eaccc1872d9660e223d06cb1ab Mon Sep 17 00:00:00 2001 From: Samuele Verzi Date: Tue, 21 Apr 2026 11:09:05 +0200 Subject: [PATCH 2/2] Return 502 Bad Gateway when OCI install pull fails installFromOCI previously mapped registry.Pull failures to 400 Bad Request, which incorrectly blamed the caller for upstream registry problems (auth, network, manifest unknown). Return 502 Bad Gateway to match the behaviour just applied to GetContent and the existing git install path. --- pkg/skills/skillsvc/install_oci.go | 2 +- pkg/skills/skillsvc/install_oci_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/skills/skillsvc/install_oci.go b/pkg/skills/skillsvc/install_oci.go index e081b04338..bdd7bad17f 100644 --- a/pkg/skills/skillsvc/install_oci.go +++ b/pkg/skills/skillsvc/install_oci.go @@ -56,7 +56,7 @@ func (s *service) installFromOCI( if err != nil { return nil, httperr.WithCode( fmt.Errorf("pulling OCI artifact %q: %w", ociRef, err), - http.StatusBadRequest, + http.StatusBadGateway, ) } diff --git a/pkg/skills/skillsvc/install_oci_test.go b/pkg/skills/skillsvc/install_oci_test.go index 3cefda2b9a..9a51da7ac5 100644 --- a/pkg/skills/skillsvc/install_oci_test.go +++ b/pkg/skills/skillsvc/install_oci_test.go @@ -579,7 +579,7 @@ func TestInstallQualifiedNameOCIFallback(t *testing.T) { // No lookup mock — gomock will fail the test if SearchSkills is called. return nil, reg, ociStore, nil, store, pr }, - wantCode: http.StatusBadRequest, + wantCode: http.StatusBadGateway, wantErr: "auth required", }, { @@ -604,7 +604,7 @@ func TestInstallQualifiedNameOCIFallback(t *testing.T) { store := storemocks.NewMockSkillStore(ctrl) return lookup, reg, ociStore, nil, store, pr }, - wantCode: http.StatusBadRequest, + wantCode: http.StatusBadGateway, wantErr: "no such host", }, { @@ -625,7 +625,7 @@ func TestInstallQualifiedNameOCIFallback(t *testing.T) { // No lookup mock — gomock will fail the test if SearchSkills is called. return nil, reg, ociStore, nil, store, pr }, - wantCode: http.StatusBadRequest, + wantCode: http.StatusBadGateway, wantErr: "manifest unknown", }, { @@ -645,7 +645,7 @@ func TestInstallQualifiedNameOCIFallback(t *testing.T) { // No lookup mock — gomock will fail if SearchSkills is called. return nil, reg, ociStore, nil, store, pr }, - wantCode: http.StatusBadRequest, + wantCode: http.StatusBadGateway, wantErr: "auth required", }, {