Skip to content

Fix mixed HTML+JSON error response when issue comment creation fails#36667

Closed
silverwind wants to merge 2 commits intogo-gitea:mainfrom
silverwind:commentpost
Closed

Fix mixed HTML+JSON error response when issue comment creation fails#36667
silverwind wants to merge 2 commits intogo-gitea:mainfrom
silverwind:commentpost

Conversation

@silverwind
Copy link
Copy Markdown
Member

@silverwind silverwind commented Feb 18, 2026

While posting issue comments on gitea.com, I notice it sometimes fails with toasts that show a HTML string:

image

I checked the HTTP response and found a garbled response for POST https://gitea.com/<owner>/<repo>/issues/<id>/comments of content-type text/html; charset=utf-8 that contains both html and json:

<html>...</html>
{"redirect":"/gitea/act_runner/issues/371"}

This PR is the result of Claude investigating this broken response. Full details:


When NewComment's CreateIssueComment call failed, ctx.ServerError wrote an HTML 500 page but the deferred function still ran and appended a JSON redirect to the response body, producing an invalid mixed HTML+JSON response shown as a toast error.

Fix by adding a ctx.Written() guard in the defer to skip writing when a response was already sent. Also make post-creation errors in CreateIssueComment (FindAndUpdateIssueMentions, GetIssueByID) non-fatal since the comment is already persisted at that point, preventing duplicate comments on retry.

When NewComment's CreateIssueComment call failed, ctx.ServerError wrote
an HTML 500 page but the deferred function still ran and appended a JSON
redirect to the response body, producing an invalid mixed HTML+JSON
response shown as a toast error.

Fix by adding a ctx.Written() guard in the defer to skip writing when a
response was already sent. Also make post-creation errors in
CreateIssueComment (FindAndUpdateIssueMentions, GetIssueByID) non-fatal
since the comment is already persisted at that point, preventing
duplicate comments on retry.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Feb 18, 2026
@github-actions github-actions bot added the modifies/go Pull requests that update Go code label Feb 18, 2026
@silverwind silverwind requested a review from Copilot February 18, 2026 04:18
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 a malformed response scenario in the web issue comment creation flow where an error page response could be followed by a deferred JSON redirect, producing a mixed/invalid response body.

Changes:

  • Add a ctx.Written() guard in NewComment’s deferred redirect to avoid writing after an error response is already sent.
  • Make mention-update and issue-reload failures in CreateIssueComment non-fatal (log and continue) to avoid retry-caused duplicate comments after persistence.
  • Add an integration test ensuring failed comment creation returns clean JSON without an appended redirect.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tests/integration/issue_test.go Adds an integration test asserting error responses are valid JSON and don’t include a deferred redirect.
services/issue/comments.go Logs (instead of returning) post-persistence errors during mention update / issue reload.
routers/web/repo/issue_comment.go Prevents deferred JSON redirect from appending to an already-written error response.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Use a temporary variable so issue is only overwritten on success,
preventing a nil dereference in notify_service.CreateIssueComment.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
mentions, err := issues_model.FindAndUpdateIssueMentions(ctx, issue, doer, comment.Content)
if err != nil {
return nil, err
log.Error("FindAndUpdateIssueMentions: %v", err)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It needs to return err

issue, err = issues_model.GetIssueByID(ctx, issue.ID)
if err != nil {
return nil, err
if reloadedIssue, err := issues_model.GetIssueByID(ctx, issue.ID); err != nil {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

It needs to return err

@wxiaoguang
Copy link
Copy Markdown
Contributor

Fix by adding a ctx.Written() guard in the defer to skip writing when a response was already sent. Also make post-creation errors in CreateIssueComment (FindAndUpdateIssueMentions, GetIssueByID) non-fatal since the comment is already persisted at that point, preventing duplicate comments on retry.

You need to figure out why they return errors, and only ignore the errors you understand

@wxiaoguang wxiaoguang marked this pull request as draft February 18, 2026 12:54
@silverwind
Copy link
Copy Markdown
Member Author

silverwind commented Feb 18, 2026

Fix by adding a ctx.Written() guard in the defer to skip writing when a response was already sent. Also make post-creation errors in CreateIssueComment (FindAndUpdateIssueMentions, GetIssueByID) non-fatal since the comment is already persisted at that point, preventing duplicate comments on retry.

You need to figure out why they return errors, and only ignore the errors you understand

I have no way to reproduce this currently, the actual cause for the 500s should be visible in gitea.com logs. Maybe it is something specific to that instance. In any case, the garbled HTML+JSON response is definitely a bug.

@silverwind silverwind changed the title Fix garbled error response when issue comment creation fails Fix mixed HTML+JSON error response when issue comment creation fails Feb 19, 2026
@silverwind
Copy link
Copy Markdown
Member Author

#36772 likely another case of mixed HTML+JSON response.

@wxiaoguang
Copy link
Copy Markdown
Contributor

#36772 likely another case of mixed HTML+JSON response.

No, it can't be.

@silverwind
Copy link
Copy Markdown
Member Author

Maybe not mixed, but HTML response on a JSON endpoint is definitely wrong.

@wxiaoguang
Copy link
Copy Markdown
Contributor

Maybe not mixed, but HTML response on a JSON endpoint is definitely wrong.

Yes, it is wrong.

I have spent a lot of time on the "route handler" framework, but there are still a lot of things to do, while nobody is interested in the following up changes.

@silverwind
Copy link
Copy Markdown
Member Author

silverwind commented Mar 2, 2026

I guess I will do a validation pass here with Claude to find any endpoints that expect JSON on frontend but can end up returning HTML in backend (like in case of errors). That should hopefully eliminate all these <!DOCTYPE toast errors.

@wxiaoguang
Copy link
Copy Markdown
Contributor

I guess I will do a validation pass here with Claude to find any endpoints that expect JSON on frontend but can end up returning HTML in backend (like in case of errors). That should hopefully eliminate all these <!DOCTYPE toast errors.

If it can do right, but not just keeps introducing duplicate or messy code.

@wxiaoguang wxiaoguang mentioned this pull request Apr 2, 2026
@silverwind
Copy link
Copy Markdown
Member Author

Closing as per #37077 (comment). Maybe I will re-visit it later after that is merged.

@silverwind silverwind closed this Apr 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. modifies/go Pull requests that update Go code type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants