Pages API returns 500 when enabling the unique domain for a project that has none

Summary

PATCH /projects/19019153/pages with pages_unique_domain_enabled=true returns 500 Internal Server Error for a project whose project_setting.pages_unique_domain is NULL. Projects created before unique domains existed never got one, so they cannot enable it through the API (and therefore not through the Terraform provider's gitlab_project_pages_settings resource). The UI checkbox works for the same project.

Steps to reproduce

  1. Take a project created before Pages unique domains, with Pages enabled and pages_unique_domain_enabled: false.
  2. curl -X PATCH --header "PRIVATE-TOKEN: ..." "https://gitlab.com/api/v4/projects/19019153/pages?pages_unique_domain_enabled=true"

Result: {"message":"500 Internal Server Error"}. The Rails log shows Validation failed: Pages unique domain can't be blank.

Cause

Pages::UpdateService#update_pages_project_settings! calls project.project_setting.update!(pages_unique_domain_enabled: true) without generating a domain. ProjectSetting validates pages_unique_domain for presence when the flag is on (require_unique_domain?), so update! raises ActiveRecord::RecordInvalid, which the API does not handle. The UI path, Projects::UpdateService#add_pages_unique_domain, calls Gitlab::Pages.add_unique_domain_to(project) first, which is why the checkbox works.

Proposal

In Pages::UpdateService, generate the unique domain (as Gitlab::Pages.generate_unique_domain does) when enabling the flag and no domain exists yet, and turn validation errors into a 422 response instead of a 500.

Edited by Timo Furrer