fix(api): don't panic on null milestone due_on (#40171)

On release/v28, `PATCH /repos/{owner}/{repo}/milestones/{id}` with
`"due_on": null`, the documented way to remove a deadline, returns HTTP
500. The backport https://github.com/go-gitea/gitea/pull/39921 changed
`EditMilestoneOption.Deadline` to `optional.Option[*string]`, which
decodes `null` as a slice holding a nil pointer, and the go-chi/binding
validator panics on that element (`reflect: call of
reflect.Value.Interface on zero Value`).

The field has no binding rules, so tag it `form:"-"` to skip validation.
main is unaffected since https://github.com/go-gitea/gitea/pull/39528
moved the binding into Gitea.
This commit is contained in:
silverwind authored and GitHub committed 2026-11-04 06:08:08 +00:00
1 parent a67b72e57b
commit 5aea433c71
2 files changed
+6 -4

No files matched your search

+1 -1
View File
@@ -58,5 +58,5 @@ type EditMilestoneOption struct {
State *string `json:"state"`
// Deadline is the due date for the milestone, use null or empty string to remove the deadline
// swagger:strfmt date-time
Deadline optional.Option[*string] `json:"due_on,omitzero"`
Deadline optional.Option[*string] `json:"due_on,omitzero" form:"-"` // go-chi/binding panics validating the nil element a JSON null decodes to
}
@@ -49,9 +49,11 @@ func TestAPIIssuesMilestone(t *testing.T) {
apiMilestone2 := DecodeJSON(t, resp, &structs.Milestone{})
assert.EqualValues(t, "closed", apiMilestone2.State)
req = NewRequestWithJSON(t, "PATCH", urlStr, map[string]any{"due_on": ""}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
assert.Nil(t, DecodeJSON(t, resp, &structs.Milestone{}).Deadline)
for _, dueOn := range []any{"", nil} {
req = NewRequestWithJSON(t, "PATCH", urlStr, map[string]any{"due_on": dueOn}).AddTokenAuth(token)
resp = MakeRequest(t, req, http.StatusOK)
assert.Nil(t, DecodeJSON(t, resp, &structs.Milestone{}).Deadline)
}
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/milestones", owner.Name, repo.Name), structs.CreateMilestoneOption{
Title: "wow",