Skip to content

backend/helm: fix double-write HTTP response and missing headers#5056

Open
NAME-ASHWANIYADAV wants to merge 7 commits intokubernetes-sigs:mainfrom
NAME-ASHWANIYADAV:fix/helm-error-handling
Open

backend/helm: fix double-write HTTP response and missing headers#5056
NAME-ASHWANIYADAV wants to merge 7 commits intokubernetes-sigs:mainfrom
NAME-ASHWANIYADAV:fix/helm-error-handling

Conversation

@NAME-ASHWANIYADAV
Copy link
Copy Markdown
Contributor

Fixes #5055

What this PR does

This PR fixes three related HTTP response handling defects in the Helm backend handlers.

1. Fix missing return after http.Error in ListCharts

File: backend/pkg/helm/charts.go

When listCharts() failed, the handler called http.Error() but did not return. Execution fell through to w.WriteHeader(http.StatusOK), producing:

  • A Go runtime warning: http: superfluous response.WriteHeader call
  • A corrupted HTTP response (500 body followed by 200 header)

2. Fix Content-Type header ordering in ListCharts and ListRepo

Files: backend/pkg/helm/charts.go, backend/pkg/helm/repository.go

Both handlers set Content-Type after WriteHeader(). In Go's net/http, WriteHeader sends the response headers immediately — any header mutations afterward are silently ignored. This meant Content-Type: application/json was never sent to clients.

3. Add structured logging to charts.go

Unlike repository.go and release.go, charts.go had no logger.Log calls. Added structured logging for both error paths in ListCharts for consistent observability.

Testing

New tests added

Test File What it validates
TestListChartError charts_test.go Verifies ListCharts returns HTTP 500 (not 200) when chart listing fails, and does not leak a JSON body
TestListChartContentType charts_test.go Verifies Content-Type: application/json header is correctly set on success responses
TestListRepositoriesContentType repository_test.go Verifies Content-Type: application/json header is correctly set for ListRepo

Verification results

  • go vet ./pkg/helm/ — Clean (exit code 0)
  • go fmt ./pkg/helm/ — No changes needed
  • go test ./pkg/helm/ -v — All 8 tests pass (1.712s)
Test Result
TestListChart PASS (0.53s)
TestListChartError PASS (0.00s)
TestListChartContentType PASS (0.19s)
TestAddRepository PASS (0.20s)
TestRemoveRepository PASS (0.17s)
TestUpdateRepo PASS (0.17s)
TestListRepositories PASS (0.18s)
TestListRepositoriesContentType PASS (0.19s)

Changes

File Changes
backend/pkg/helm/charts.go Fix missing return, fix header ordering, add logger.Log
backend/pkg/helm/repository.go Fix header ordering in ListRepo
backend/pkg/helm/charts_test.go Add TestListChartError, TestListChartContentType
backend/pkg/helm/repository_test.go Add TestListRepositoriesContentType

@k8s-ci-robot k8s-ci-robot requested review from illume and yolossn April 4, 2026 15:51
@k8s-ci-robot k8s-ci-robot added size/M Denotes a PR that changes 30-99 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. labels Apr 4, 2026
@NAME-ASHWANIYADAV
Copy link
Copy Markdown
Contributor Author

@illume hii !
i will appreciate a review from you whenever you have free time
🤞🙏

@NAME-ASHWANIYADAV
Copy link
Copy Markdown
Contributor Author

/assign @illume

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes HTTP response handling issues in Helm backend handlers to prevent double-writing responses and ensure JSON Content-Type headers are actually sent.

Changes:

  • Add missing return after http.Error in ListCharts and add structured logging for ListCharts error paths.
  • Set Content-Type: application/json before WriteHeader() in ListCharts and ListRepo so clients receive the header.
  • Add/extend tests to validate Content-Type and the ListCharts error status code.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
backend/pkg/helm/charts.go Fix ListCharts error fallthrough, correct header ordering, add structured logs.
backend/pkg/helm/repository.go Correct Content-Type header ordering in ListRepo.
backend/pkg/helm/charts_test.go Add tests for ListCharts error status and Content-Type header.
backend/pkg/helm/repository_test.go Add test ensuring ListRepo sets Content-Type correctly.

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: NAME-ASHWANIYADAV
Once this PR has been reviewed and has the lgtm label, please ask for approval from illume. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@NAME-ASHWANIYADAV
Copy link
Copy Markdown
Contributor Author

Fixed: changed the indentation of the space to match the other files in the package.
plz re-review @illume

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

Comment on lines +72 to +77
func TestListChartError(t *testing.T) {
// Create a handler with invalid settings that will cause listCharts to fail.
// Using a non-existent repository config path forces a repo.LoadFile error.
invalidSettings := cli.New()
invalidSettings.RepositoryConfig = "/non-existent-path/repositories.yaml"

Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestListChartError hard-codes an absolute path ("/non-existent-path/repositories.yaml") to force repo.LoadFile to fail. This can be non-deterministic if that path exists in some environments and is less portable across OSes. Prefer using t.TempDir() + filepath.Join(...) to construct a guaranteed-nonexistent file path under a temp directory (or create an invalid YAML file there) so the failure is deterministic.

Copilot uses AI. Check for mistakes.
Comment on lines 238 to 244
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)

err = json.NewEncoder(w).Encode(response)
if err != nil {
logger.Log(logger.LevelError, nil, err, "encoding response")
http.Error(w, err.Error(), http.StatusInternalServerError)

return
}
Copy link

Copilot AI Apr 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ListRepo writes the 200 status and starts the response before calling json.Encoder.Encode. If encoding fails (e.g., client disconnect / write error), the handler can only log and cannot reliably communicate failure to the client because headers are already sent. Consider encoding into an intermediate buffer first and only then setting headers + status and writing the body, so true encoding failures can return a 5xx cleanly without partially-written JSON.

Copilot uses AI. Check for mistakes.
@NAME-ASHWANIYADAV
Copy link
Copy Markdown
Contributor Author

@illume i have implemented the changes and updated the code based on copilot
May u plz re-review it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/M Denotes a PR that changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Helm handlers: missing return after http.Error and Content-Type header set after WriteHeader

4 participants