{"record":{"id":"a7c655f180e38ddb","repo":"SonarSource/sonarqube","slug":"your-gitlab-global-configuration-is-incomplete-th","errorCode":null,"errorMessage":"Your Gitlab global configuration is incomplete. The GitLab URL must be set.","messagePattern":"Your Gitlab global configuration is incomplete\\. The GitLab URL must be set\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabGlobalSettingsValidator.java","lineNumber":66,"sourceCode":"  private static final String API_SCOPE = \"api\";\n\n  private final Encryption encryption;\n  private final GitlabApplicationClient gitlabApplicationClient;\n\n  public GitlabGlobalSettingsValidator(GitlabApplicationClient gitlabApplicationClient, Settings settings) {\n    this.encryption = settings.getEncryption();\n    this.gitlabApplicationClient = gitlabApplicationClient;\n  }\n\n  public void validate(AlmSettingDto almSettingDto) {\n    String gitlabUrl = almSettingDto.getUrl();\n    String accessToken = almSettingDto.getDecryptedPersonalAccessToken(encryption);\n    validate(ValidationMode.COMPLETE, gitlabUrl, accessToken);\n  }\n\n  public void validate(ValidationMode validationMode, @Nullable String gitlabApiUrl, @Nullable String accessToken) {\n    if (gitlabApiUrl == null) {\n      throw new IllegalArgumentException(\"Your Gitlab global configuration is incomplete. The GitLab URL must be set.\");\n    }\n    gitlabApplicationClient.checkUrl(gitlabApiUrl);\n    if (ValidationMode.AUTH_ONLY.equals(validationMode)) {\n      return;\n    }\n\n    String decryptedToken = getDecryptedToken(accessToken);\n    if (decryptedToken == null) {\n      throw new IllegalArgumentException(\"Your Gitlab global configuration is incomplete. The GitLab access token must be set.\");\n    }\n    gitlabApplicationClient.checkToken(gitlabApiUrl, decryptedToken);\n    gitlabApplicationClient.checkReadPermission(gitlabApiUrl, decryptedToken);\n    gitlabApplicationClient.checkWritePermission(gitlabApiUrl, decryptedToken);\n  }\n\n  /**\n   * Whether the given configuration's token has the {@code api} scope, the only scope that grants the write access\n   * the Remediation Agent needs (create branches, open merge requests). Introspects the token directly via","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/gitlab/GitlabGlobalSettingsValidator.java#L48-L84","documentation":"GitlabGlobalSettingsValidator.validate checks the global GitLab ALM configuration. When the GitLab URL is null (not configured in global ALM settings), validation fails immediately with this IllegalArgumentException before any remote call is attempted. The global GitLab integration cannot be used or tested without a URL.","triggerScenarios":"Calling validate(almSettingDto, encryption) or validate(validationMode, null, accessToken) when the GitLab global ALM setting has no URL stored — e.g. testing the configuration before the URL was saved, or after the URL field was cleared.","commonSituations":"Setting up GitLab integration for the first time and hitting 'Validate' before filling the URL; configuration import/migration losing the url field; API calls creating ALM settings without the url property; clearing the URL in Administration > DevOps Platform Integration.","solutions":["Set the GitLab URL in Administration > Configuration > DevOps Platform Integration (e.g. https://gitlab.example.com).","Via API/WebService, ensure the alm_settings update includes the url parameter before validating.","Re-create or repair the ALM setting row so almSettingDto.getUrl() returns the instance URL.","Check the client passes the URL correctly to the validator (not null from decryption/config layer)."],"exampleFix":"// before: validating with missing URL\nvalidator.validate(ValidationMode.COMPLETE, null, accessToken);\n// after: guard/ensure URL configured first\nif (almSettingDto.getUrl() != null) {\n  validator.validate(ValidationMode.COMPLETE, almSettingDto.getUrl(), accessToken);\n}","handlingStrategy":"validation","validationCode":"if (almSettingDto == null || almSettingDto.getUrl() == null || almSettingDto.getUrl().isBlank()) {\n  throw new IllegalStateException(\"Set the GitLab URL in DevOps Platform Integration settings before validating\");\n}","typeGuard":"boolean hasGitlabUrl(AlmSettingDto dto) { return dto != null && dto.getUrl() != null && !dto.getUrl().isBlank(); }","tryCatchPattern":"try { validator.validate(almSettingDto, encryption); } catch (IllegalArgumentException e) { /* prompt admin to set GitLab URL */ }","preventionTips":["Always save the URL field before clicking 'Validate' in the ALM settings UI","Include the url parameter in alm_settings web service calls","Audit config imports/migrations for dropped url fields"],"tags":["gitlab","configuration","missing-url","validation"],"backgroundTag":"missing-required-config-field","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}