{"record":{"id":"d4bc0b990116c6de","repo":"SonarSource/sonarqube","slug":"failed-to-construct-github-repository-url-for-alm","errorCode":null,"errorMessage":"Failed to construct GitHub repository URL for ALM setting '{}' and repository '{}'","messagePattern":"Failed to construct GitHub repository URL for ALM setting '(.+?)' and repository '(.+?)'","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java","lineNumber":153,"sourceCode":"      } else if (almSetting.getAlm() == ALM.BITBUCKET) {\n        setBitbucketServerRepositoryUrl(almSetting, projectAlmSetting, builder);\n      }\n\n      return builder.build();\n    }\n  }\n\n  private static void setGithubRepositoryUrl(AlmSettingDto almSetting, ProjectAlmSettingDto projectAlmSetting, GetBindingWsResponse.Builder builder) {\n    if (isNotBlank(projectAlmSetting.getAlmRepo()) && isNotBlank(almSetting.getUrl())) {\n      try {\n        String baseUrl = GithubApplicationClientImpl.convertApiUrlToBaseUrl(requireNonNull(almSetting.getUrl()));\n        HttpUrl repositoryUrl = HttpUrl.parse(baseUrl)\n          .newBuilder()\n          .addPathSegments(requireNonNull(projectAlmSetting.getAlmRepo()))\n          .build();\n        builder.setRepositoryUrl(repositoryUrl.toString());\n      } catch (Exception e) {\n        LOG.warn(\"Failed to construct GitHub repository URL for ALM setting '{}' and repository '{}'\",\n          almSetting.getKey(), projectAlmSetting.getAlmRepo(), e);\n      }\n    }\n  }\n\n  private void setGitlabRepositoryUrl(AlmSettingDto almSetting, ProjectAlmSettingDto projectAlmSetting, GetBindingWsResponse.Builder builder) {\n    if (isNotBlank(projectAlmSetting.getAlmRepo()) && isNotBlank(almSetting.getUrl())) {\n      try {\n        String personalAccessToken = almSetting.getDecryptedPersonalAccessToken(encryption);\n        if (isNotBlank(personalAccessToken)) {\n          Long gitlabProjectId = Long.parseLong(requireNonNull(projectAlmSetting.getAlmRepo()));\n          Project gitlabProject = gitlabApplicationClient.getProject(\n            requireNonNull(almSetting.getUrl()),\n            personalAccessToken,\n            gitlabProjectId);\n          builder.setRepositoryUrl(gitlabProject.getWebUrl());\n        }\n      } catch (NumberFormatException e) {","sourceCodeStart":135,"sourceCodeEnd":171,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-webapi/src/main/java/org/sonar/server/almsettings/ws/GetBindingAction.java#L135-L171","documentation":"This warning is logged by GetBindingAction.setGithubRepositoryUrl when SonarQube cannot build the web URL of a GitHub repository while serving the ALM binding lookup request. It parses the configured GitHub base URL and appends the stored almRepo path segment; any failure (unparseable URL, null/blank repo) is swallowed and logged as a warning so the binding response is still returned without a repositoryUrl.","triggerScenarios":"GET api/alm_settings/get_binding for a GitHub-bound project where almSetting.getUrl() is malformed or not parseable by OkHttp's HttpUrl.parse, or projectAlmSetting.getAlmRepo() is null (requireNonNull throws NPE) or contains characters that break URL building.","commonSituations":"A GitHub ALM setting whose URL was entered as 'github.mycompany.com' without an https:// scheme; a project binding persisted before the repo field was populated; an import/migration leaving almRepo null.","solutions":["Fix the GitHub ALM setting URL in Administration > DevOps Platform Integrations so it is a fully qualified, parseable URL (e.g. https://github.mycompany.com/ or https://github.com/)","Re-bind the project via api/alm_settings/set_binding or the project's ALM binding page so almRepo is populated with the correct 'org/repo' value","Verify with GET api/alm_settings/get_binding (or list_alm_settings) that almRepo is non-null for the project","Check the server log stack trace attached to this warning to identify which field failed (URL parse vs null repo)"],"exampleFix":"// before: almSetting url \"github.company.com\"\n// after: update ALM setting with a valid absolute URL\ncurl -X POST -u admin:token 'https://sonar.example.com/api/alm_settings/update_github' -d 'key=github-app-id' -d 'url=https://github.company.com'","handlingStrategy":"validation","validationCode":"// Validate before configuring the ALM setting / binding\nString url = almSetting.getUrl();\nif (url == null || OkHttp.parse(url) == null) throw new IllegalArgumentException(\"GitHub ALM setting URL must be an absolute http(s) URL\");\nif (projectAlmSetting.getAlmRepo() == null || projectAlmSetting.getAlmRepo().isBlank()) throw new IllegalArgumentException(\"almRepo (org/repo) is required\");","typeGuard":null,"tryCatchPattern":"// The server already swallows this; clients of get_binding should treat missing repositoryUrl as degraded data\nGetBindingWsResponse r = service.getBinding(request);\nif (!r.hasRepositoryUrl()) { /* re-bind or fix ALM setting */ }","preventionTips":["Always enter ALM URLs with an explicit https:// scheme","Require almRepo (org/repo) to be set at binding time, not just the setting","Validate ALM settings via api/alm_settings/list after creation","Watch for this warning after migrations/imports of ALM settings"],"tags":["alm-integration","github","url-construction","logging"],"backgroundTag":"invalid-url-format","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"}