500 error on Projects get/list API when a project repository is missing
Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.
I'm using GitLab 14.0.12-ce, and I have some projects which are missing their repository, despite the git repository not being an explicitly disabled feature:
I don't know why yet, but that's not the point here.
When I try to list all Projects from this server (here using python-gitlab CLI), I get a 500 error on pages which include such projects:
$ gitlab --debug project list --order-by id --sort asc --per-page 10 --page 83
send: b'GET /api/v4/projects?order_by=id&sort=asc&page=83&per_page=10 HTTP/1.1\r\nHost: XXXXXXXXXXXXX\r\nUser-Agent: python-gitlab/2.10.1\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nPRIVATE-TOKEN: XXXXXXXXXXXXX\r\nContent-type: application/json\r\n\r\n'
reply: 'HTTP/1.1 500 Internal Server Error\r\n'
header: server: nginx
header: date: Wed, 15 Dec 2021 23:37:17 GMT
header: content-type: application/json
header: content-length: 39
header: cache-control: no-cache
header: vary: Origin
header: x-request-id: XXXXXXXXXXXXX
header: x-runtime: 0.252102
header: strict-transport-security: max-age=63072000
DEBUG:urllib3.connectionpool:https://XXXXXXXXXXXXX:443 "GET /api/v4/projects?order_by=id&sort=asc&page=83&per_page=10 HTTP/1.1" 500 39
Impossible to list objects (500: 500 Internal Server Error)
Same if I try to get one single such projects:
$ gitlab --debug project get --id 1907
send: b'GET /api/v4/projects/1907 HTTP/1.1\r\nHost: XXXXXXXXXXXXX\r\nUser-Agent: python-gitlab/2.10.1\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection: keep-alive\r\nPRIVATE-TOKEN: XXXXXXXXXXXXX\r\nContent-type: application/json\r\n\r\n'
reply: 'HTTP/1.1 500 Internal Server Error\r\n'
header: server: nginx
header: date: Wed, 15 Dec 2021 23:40:50 GMT
header: content-type: application/json
header: content-length: 39
header: cache-control: no-cache
header: vary: Origin
header: x-request-id: XXXXXXXXXXXXX
header: x-runtime: 0.057094
header: strict-transport-security: max-age=63072000
DEBUG:urllib3.connectionpool:https://XXXXXXXXXXXXX:443 "GET /api/v4/projects/1907 HTTP/1.1" 500 39
Impossible to get object (500: 500 Internal Server Error)
The exceptions log shows the relevant stack, something like this:
{
"severity": "ERROR",
"time": "2021-12-15T08:26:25.125Z",
"correlation_id": "XXXXXXXXXXXXX",
"exception.class": "TypeError",
"exception.message": "no implicit conversion of nil into String",
"exception.backtrace": [
"app/models/project.rb:1319:in `join'",
"app/models/project.rb:1319:in `readme_url'",
"lib/gitlab/metrics/instrumentation.rb:160:in `block in readme_url'",
"lib/gitlab/metrics/method_call.rb:27:in `measure'",
"lib/gitlab/metrics/instrumentation.rb:160:in `readme_url'",
"lib/gitlab/json.rb:110:in `dump'",
"lib/gitlab/json.rb:110:in `adapter_dump'",
"lib/gitlab/json.rb:42:in `dump'",
"lib/gitlab/json.rb:198:in `call'",
"lib/api/api_guard.rb:213:in `call'",
"lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'",
"lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'",
"lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'",
"lib/gitlab/metrics/web_transaction.rb:21:in `run'",
"lib/gitlab/metrics/rack_middleware.rb:16:in `call'",
"lib/gitlab/middleware/speedscope.rb:13:in `call'",
"lib/gitlab/request_profiler/middleware.rb:17:in `call'",
"lib/gitlab/jira/middleware.rb:19:in `call'",
"lib/gitlab/middleware/go.rb:20:in `call'",
"lib/gitlab/etag_caching/middleware.rb:21:in `call'",
"lib/gitlab/middleware/multipart.rb:172:in `call'",
"lib/gitlab/middleware/read_only/controller.rb:50:in `call'",
"lib/gitlab/middleware/read_only.rb:18:in `call'",
"lib/gitlab/middleware/same_site_cookies.rb:27:in `call'",
"lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'",
"lib/gitlab/middleware/basic_health_check.rb:25:in `call'",
"lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'",
"lib/gitlab/middleware/request_context.rb:21:in `call'",
"config/initializers/fix_local_cache_middleware.rb:11:in `call'",
"lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'",
"lib/gitlab/metrics/requests_rack_middleware.rb:74:in `call'",
"lib/gitlab/middleware/release_env.rb:12:in `call'"
],
"user.username": "root",
"tags.program": "web",
"tags.locale": "en",
"tags.feature_category": "projects",
"tags.correlation_id": "XXXXXXXXXXXXX"
}
I know I'm using a rather old GitLab version (14.0.x), but I don't think this has been fixed yet:
I'm not a Ruby dev', but my understanding is that the case of default_branch being nil is not handled. Probably it should end up with readme_url returning nil too, like when there is no repository.readme_path.