Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SyntaxError: Unexpected end of JSON input when creating a merge request #31625

Closed
T-baby opened this issue Jul 12, 2024 · 17 comments · Fixed by #31843
Closed

SyntaxError: Unexpected end of JSON input when creating a merge request #31625

T-baby opened this issue Jul 12, 2024 · 17 comments · Fixed by #31843
Labels
issue/needs-feedback For bugs, we need more details. For features, the feature must be described in more detail type/bug
Milestone

Comments

@T-baby
Copy link

T-baby commented Jul 12, 2024

Description

When trying to create a merge request in a self-hosted Gitea instance, a toast notification pops up with the message: "SyntaxError: Unexpected end of JSON input". After checking the server logs, no errors were found.

Gitea Version

1.22.0

Can you reproduce the bug on the Gitea demo site?

No

Log Gist

No response

Screenshots

No response

Git Version

No response

Operating System

No response

How are you running Gitea?

Docker, version 20.10.17, running on Ubuntu 22.04.

Database

PostgreSQL

@techknowlogick
Copy link
Member

Thanks for your report, are you able to share details of the developer console in your browser, or network tab showing what the http response shows?

@techknowlogick techknowlogick added the issue/needs-feedback For bugs, we need more details. For features, the feature must be described in more detail label Jul 13, 2024
@T-baby
Copy link
Author

T-baby commented Jul 15, 2024

image
image

@matrixcloud
Copy link

same issue, any solution?

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Jul 25, 2024

There were many similar reports: check your reverse-proxy (eg: nginx) & firewall & WAF, do not "deny" some requests for Gitea's backend.

If there is still a problem, please show your full configuration (including Gitea's app.ini and your reverse-proxy config), and provide a reproducible setup with detailed steps.

@T-baby
Copy link
Author

T-baby commented Jul 25, 2024

No WAF and CDN was used, only Nginx was used for reverse proxy. The Nginx configuration is as follows:

server {
    listen       80;
    server_name  xx;
    client_max_body_size 10G;
    location / {
        proxy_pass http://gitea:3000;
        index  index.html index.htm;
    }
}


server {
    listen       443 ssl;
    server_name  xx;
    client_max_body_size 10G;
    client_header_timeout 1800s;
    client_body_timeout 1800s;
    send_timeout 1800s;
    proxy_connect_timeout 1800s;
    proxy_read_timeout 1800s;
    proxy_send_timeout 1800s;
    ssl_certificate crt;
        ssl_certificate_keykey;

    location / {
        proxy_pass http://gitea:3000;
        index  index.html index.htm;
    }
}

@wxiaoguang
Copy link
Contributor

  1. Please check your browser's console, to see the request URL and response header / response body. There must be some clues.
  2. Please provide a reproducible setup with detailed steps. Only if it could be reproduced by others, it could have a chance to be resolved.

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Jul 25, 2024

ps: Nginx could have various plugins. , so "please show your full configuration", eg: nginx -T

The config you shown is not the real one you are using, because I can see you manually prettified / changed it.

@T-baby
Copy link
Author

T-baby commented Jul 25, 2024

This request url is: https://xx/xx/project/compare/develop...feat/dev_test

This request headers is:

image

This response headers is:

image

This response body is null.

The full configuration of nginx:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
# configuration file /etc/nginx/nginx.conf:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    client_max_body_size  45M;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    include /etc/nginx/conf.d/*.conf;
}

# configuration file /etc/nginx/mime.types:

types {
    text/html                                        html htm shtml;
    text/css                                         css;
    text/xml                                         xml;
    image/gif                                        gif;
    image/jpeg                                       jpeg jpg;
    application/javascript                           js;
    application/atom+xml                             atom;
    application/rss+xml                              rss;

    text/mathml                                      mml;
    text/plain                                       txt;
    text/vnd.sun.j2me.app-descriptor                 jad;
    text/vnd.wap.wml                                 wml;
    text/x-component                                 htc;

    image/avif                                       avif;
    image/png                                        png;
    image/svg+xml                                    svg svgz;
    image/tiff                                       tif tiff;
    image/vnd.wap.wbmp                               wbmp;
    image/webp                                       webp;
    image/x-icon                                     ico;
    image/x-jng                                      jng;
    image/x-ms-bmp                                   bmp;

    font/woff                                        woff;
    font/woff2                                       woff2;

    application/java-archive                         jar war ear;
    application/json                                 json;
    application/mac-binhex40                         hqx;
    application/msword                               doc;
    application/pdf                                  pdf;
    application/postscript                           ps eps ai;
    application/rtf                                  rtf;
    application/vnd.apple.mpegurl                    m3u8;
    application/vnd.google-earth.kml+xml             kml;
    application/vnd.google-earth.kmz                 kmz;
    application/vnd.ms-excel                         xls;
    application/vnd.ms-fontobject                    eot;
    application/vnd.ms-powerpoint                    ppt;
    application/vnd.oasis.opendocument.graphics      odg;
    application/vnd.oasis.opendocument.presentation  odp;
    application/vnd.oasis.opendocument.spreadsheet   ods;
    application/vnd.oasis.opendocument.text          odt;
    application/vnd.openxmlformats-officedocument.presentationml.presentation
                                                     pptx;
    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
                                                     xlsx;
    application/vnd.openxmlformats-officedocument.wordprocessingml.document
                                                     docx;
    application/vnd.wap.wmlc                         wmlc;
    application/wasm                                 wasm;
    application/x-7z-compressed                      7z;
    application/x-cocoa                              cco;
    application/x-java-archive-diff                  jardiff;
    application/x-java-jnlp-file                     jnlp;
    application/x-makeself                           run;
    application/x-perl                               pl pm;
    application/x-pilot                              prc pdb;
    application/x-rar-compressed                     rar;
    application/x-redhat-package-manager             rpm;
    application/x-sea                                sea;
    application/x-shockwave-flash                    swf;
    application/x-stuffit                            sit;
    application/x-tcl                                tcl tk;
    application/x-x509-ca-cert                       der pem crt;
    application/x-xpinstall                          xpi;
    application/xhtml+xml                            xhtml;
    application/xspf+xml                             xspf;
    application/zip                                  zip;

    application/octet-stream                         bin exe dll;
    application/octet-stream                         deb;
    application/octet-stream                         dmg;
    application/octet-stream                         iso img;
    application/octet-stream                         msi msp msm;

    audio/midi                                       mid midi kar;
    audio/mpeg                                       mp3;
    audio/ogg                                        ogg;
    audio/x-m4a                                      m4a;
    audio/x-realaudio                                ra;

    video/3gpp                                       3gpp 3gp;
    video/mp2t                                       ts;
    video/mp4                                        mp4;
    video/mpeg                                       mpeg mpg;
    video/quicktime                                  mov;
    video/webm                                       webm;
    video/x-flv                                      flv;
    video/x-m4v                                      m4v;
    video/x-mng                                      mng;
    video/x-ms-asf                                   asx asf;
    video/x-ms-wmv                                   wmv;
    video/x-msvideo                                  avi;
}

# configuration file /etc/nginx/conf.d/gitea.conf:
server {
    listen       80;
    server_name  xx;
    client_max_body_size 10G;
    location / {
        proxy_pass http://gitea:3000;
        index  index.html index.htm;
    }
}


server {
    listen       443 ssl;
    server_name  xx;
    client_max_body_size 10G;
    client_header_timeout 1800s;
    client_body_timeout 1800s;
    send_timeout 1800s;
    proxy_connect_timeout 1800s;
    proxy_read_timeout 1800s;
    proxy_send_timeout 1800s;
    ssl_certificate crt;
        ssl_certificate_key key;

    location / {
        proxy_pass http://gitea:3000;
        index  index.html index.htm;
    }
}

@wxiaoguang
Copy link
Contributor

I think it is still related to your network or config.

  1. There are a lot of unrelated cookies in your request header, it seems that there might be some middle device (or app) between you and your server.
  2. I didn't not see the response code, but it is still likely the problem occurs before Gitea server (not related to Gitea), so I guess you also have never seen the "merge" request reaches Gitea server.
  3. So still the same suggestion as above:
    • Check you network & environment
    • Reproduce it on a clear server then others could help to debug
    • Otherwise I don't think we could make new progress here

@wxiaoguang
Copy link
Contributor

Maybe your request is rejected by Tencent Cloud.

image

@T-baby
Copy link
Author

T-baby commented Jul 25, 2024

I tried using it in the browser's incognito mode, but I still couldn't merge. The complete headers of requests and response are as follows:

POST /xx/xx/compare/develop...feat/dev_test HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Content-Length: 890
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryS8dz1rWTyhWCS8rN
Cookie: i_like_gitea=f033aa68145ed416; lang=zh-CN; _csrf=Hb7iUYpQYTXXr0aq9pt4RtfBA-Y6MTcyMTg3NzQxNTIyMjg2NTk5MA
DNT: 1
Host: xx
Origin: https://xx
Pragma: no-cache
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
sec-ch-ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
x-csrf-token: Hb7iUYpQYTXXr0aq9pt4RtfBA-Y6MTcyMTg3NzQxNTIyMjg2NTk5MA
HTTP/1.1 200 OK
Server: nginx/1.23.0
Date: Thu, 25 Jul 2024 03:17:45 GMT
Content-Length: 0
Connection: keep-alive
Cache-Control: max-age=0, private, must-revalidate, no-transform
X-Frame-Options: SAMEORIGIN

We are unable to create a merge request only for this repository. It works fine for all others.

@wxiaoguang
Copy link
Contributor

Try go use other servers than Tencent Cloud.

@T-baby
Copy link
Author

T-baby commented Jul 25, 2024

Try go use other servers than Tencent Cloud.

We are not using Tencent Cloud servers.

@wxiaoguang
Copy link
Contributor

Try go use other servers than Tencent Cloud.尝试使用除腾讯云之外的其他服务器。

We are not using Tencent Cloud servers.

Then: "please provide a reproducible setup with detailed steps."

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Jul 25, 2024

You could provide the reproducible setup by a docker-compose file and some related commands, to make others could also reproduce the problem on their side.

@wolfogre
Copy link
Member

I received another report similar to this issue. And this time it can indeed be found in Gitea's logs that it received the request and returned a response with zero status code.

2024/08/15 03:32:59 ...eb/routing/logger.go:102:func1() [I] router: completed POST /[hidden]/compare/[hidden]...[hidden] for [hidden], 0 in 1563.2ms @ repo/pull.go:1223(repo.CompareAndPullRequestPost)

IIRC, the framework will return 200 with an empty body if WriteHeader hasn't been called.

No idea how it could happen, but maybe there is something going wrong with Gitea.

@wolfogre wolfogre reopened this Aug 16, 2024
@lunny lunny added this to the 1.22.2 milestone Aug 16, 2024
@lunny lunny added the type/bug label Aug 16, 2024
@lunny lunny closed this as completed in acd7053 Aug 16, 2024
GiteaBot pushed a commit to GiteaBot/gitea that referenced this issue Aug 16, 2024
Fix go-gitea#31625.

If `pull_service.NewPullRequest` return an error which misses each `if`
check, `CompareAndPullRequestPost` will return immediately, since it
doesn't write the HTTP response, a 200 response with empty body will be
sent to clients.

```go
	if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil {
		if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
			ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
		} else if git.IsErrPushRejected(err) {
			// ...
			ctx.JSONError(flashError)
		} else if errors.Is(err, user_model.ErrBlockedUser) {
			// ...
			ctx.JSONError(flashError)
		} else if errors.Is(err, issues_model.ErrMustCollaborator) {
			// ...
			ctx.JSONError(flashError)
		}
		return
	}
```

Not sure what kind of error can cause it to happen, so this PR just
expose it. And we can fix it when users report that creating PRs failed
with error responses.

It's all my guess since I cannot reproduce the problem, but even if it's
not related, the code here needs to be improved.
techknowlogick pushed a commit that referenced this issue Aug 16, 2024
Backport #31843 by @wolfogre

Fix #31625.

If `pull_service.NewPullRequest` return an error which misses each `if`
check, `CompareAndPullRequestPost` will return immediately, since it
doesn't write the HTTP response, a 200 response with empty body will be
sent to clients.

```go
	if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil {
		if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
			ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
		} else if git.IsErrPushRejected(err) {
			// ...
			ctx.JSONError(flashError)
		} else if errors.Is(err, user_model.ErrBlockedUser) {
			// ...
			ctx.JSONError(flashError)
		} else if errors.Is(err, issues_model.ErrMustCollaborator) {
			// ...
			ctx.JSONError(flashError)
		}
		return
	}
```

Not sure what kind of error can cause it to happen, so this PR just
expose it. And we can fix it when users report that creating PRs failed
with error responses.

It's all my guess since I cannot reproduce the problem, but even if it's
not related, the code here needs to be improved.

Co-authored-by: Jason Song <[email protected]>
@wxiaoguang
Copy link
Contributor

More context and a new clue:

#31893 (comment)

That PR alone didn't fix it but looking at the response in the network section of the browser we were now with the nightly getting a proper error 500 back that indicated somehow there was a .lock file on that repo left over that was blocking this. i removed it and it worked!

@go-gitea go-gitea locked as resolved and limited conversation to collaborators Nov 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
issue/needs-feedback For bugs, we need more details. For features, the feature must be described in more detail type/bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants