Creating Group API resource that has duplicate name of existing record throws 500 instead of 400
Summary
When creating a new group using the API with a duplicate name of an existing group, the data validation throws a 500 error message without any context instead of the expected behavior of 400 bad request with details about the field.
This is similar to #208329 (closed) so I suspect that this affects other API resources as well.
Steps to reproduce
- Use the Web UI to create a group in a self-managed GitLab instance. Take note of the group ID number. This is used for creating child groups underneath.
- Use Postman or another API client to create a new child group. This will be the initial group. API Docs
- name:
Postman Group 1 - path:
postman-group-1a - parent_id: {group_id_from_step_1}
- name:
- Use Postman to create another group. This will be the duplicate group with the same name but a different path so it would seemingly be unique from a path perspective.
- name:
Postman Group 1 - path:
postman-group-1b - parent_id: {group_id_from_step_1}
- name:
- See the
500error message in the response. - To see the expected behavior, perform similar steps above but use different names and the same path.
- Create a baseline group.
- name:
Postman Group 2a - path:
postman-group-2 - parent_id: {group_id_from_step_1}
- name:
- Create a duplicate group.
- name:
Postman Group 2b - path:
postman-group-2 - parent_id: {group_id_from_step_1}
- name:
- See the
400error message with the response reason context about the existing value.
Reproduced steps are in screenshots below.
Example Project
N/A. See group creation steps in reproduce instructions.
What is the current bug behavior?
A 500 error is returned when a group with the same name exists.
500 Internal Server Error
What is the expected correct behavior?
A 400 error is returned with an explanation of what the problem is.
400 Bad Request
{
"message": "Failed to save group {:name=>[\"has already been taken\"]}"
}
Relevant logs and/or screenshots
Reproduce Step 2 - Creating a Baseline Group
Reproduce Step 3 - Creating a Duplicate Group (same name, different path) - Bug Behavior
Reproduce Step 6 - Create a Baseline Group
Reproduce Step 7 - Creating a Duplicate Group (different name, same path) - Expected Behavior
GitLab v13.4.1 Self Managed
/var/log/gitlab/gitlab-rails/api_json.log
{
"time":"2020-10-22T21:22:20.310Z",
"severity":"INFO",
"duration_s":0.21631,
"db_duration_s":0.15557,
"view_duration_s":0.06074,
"status":500,
"method":"POST",
"path":"/api/v4/groups",
"params":[
{
"key":"name",
"value":"Postman Group 1"
},
{
"key":"path",
"value":"postman-group-1b"
},
{
"key":"parent_id",
"value":"7209"
}
],
"host":"gitlab-core.us.gitlabdemo.cloud",
"remote_ip":"73.97.219.97, 73.97.219.97",
"ua":"PostmanRuntime/7.26.3",
"route":"/api/:version/groups",
"user_id":52,
"username":"jeffersonmartin",
"exception.class":"ActiveRecord::RecordNotUnique",
"exception.message":"PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_namespaces_on_name_and_parent_id" DETAIL: Key (name, parent_id)=(Postman Group 1, 7209) already exists. ",
"exception.backtrace":[
"app/services/groups/create_service.rb:31:in `execute'",
"ee/app/services/ee/groups/create_service.rb:10:in `execute'",
"lib/api/groups.rb:59:in `create_group'",
"ee/lib/ee/api/groups.rb:28:in `create_group'",
"lib/api/groups.rb:168:in `block (2 levels) in '",
"ee/lib/gitlab/middleware/ip_restrictor.rb:14:in `block in call'",
"ee/lib/gitlab/ip_address_state.rb:10:in `with'",
"ee/lib/gitlab/middleware/ip_restrictor.rb:13: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/transaction.rb:61:in `run'",
"lib/gitlab/metrics/rack_middleware.rb:16: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:13:in `call'",
"lib/gitlab/middleware/multipart.rb:217:in `call'",
"lib/gitlab/middleware/read_only/controller.rb:51:in `call'",
"lib/gitlab/middleware/read_only.rb:18:in `call'",
"lib/gitlab/middleware/same_site_cookies.rb:27: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:23:in `call'",
"config/initializers/fix_local_cache_middleware.rb:9:in `call'",
"lib/gitlab/metrics/requests_rack_middleware.rb:60:in `call'",
"lib/gitlab/middleware/release_env.rb:12:in `call'"
],
"queue_duration_s":0.030396,
"redis_calls":5,
"redis_duration_s":0.001689,
"redis_read_bytes":1047,
"redis_write_bytes":266,
"redis_cache_calls":5,
"redis_cache_duration_s":0.001689,
"redis_cache_read_bytes":1047,
"redis_cache_write_bytes":266,
"correlation_id":"npAB8fZmHha",
"meta.user":"jeffersonmartin",
"meta.caller_id":"/api/:version/groups"
}
Output of checks
Results of GitLab environment info
Expand for output related to GitLab environment info
System information System: Ubuntu 18.04 Proxy: no Current User: git Using RVM: no Ruby Version: 2.6.6p146 Gem Version: 2.7.10 Bundler Version:1.17.3 Rake Version: 12.3.3 Redis Version: 5.0.9 Git Version: 2.28.0 Sidekiq Version:5.2.9 Go Version: unknown GitLab information Version: 13.4.1-ee Revision: 4b9c8135cd9 Directory: /opt/gitlab/embedded/service/gitlab-rails DB Adapter: PostgreSQL DB Version: 11.9 URL: https://gitlab-core.us.gitlabdemo.cloud HTTP Clone URL: https://gitlab-core.us.gitlabdemo.cloud/some-group/some-project.git SSH Clone URL: git@gitlab-core.us.gitlabdemo.cloud:some-group/some-project.git Elasticsearch: yes Geo: no Using LDAP: no Using Omniauth: yes Omniauth Providers: GitLab Shell Version: 13.7.0 Repository storage paths: - default: /var/opt/gitlab/git-data/repositories GitLab Shell path: /opt/gitlab/embedded/service/gitlab-shell Git: /opt/gitlab/embedded/bin/git
Results of GitLab application Check
Expand for output related to the GitLab application check
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:check SANITIZE=true)(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true)(we will only investigate if the tests are passing)



