{"record":{"id":"8cf6a1041e13a3e1","repo":"SonarSource/sonarqube","slug":"missing-client-id","errorCode":null,"errorMessage":"Missing Client Id","messagePattern":"Missing Client Id","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubGlobalSettingsValidator.java","lineNumber":99,"sourceCode":"   */\n  public List<String> findMissingPermissions(AlmSettingDto almSettingDto, Map<String, String> requiredPermissions) {\n    GithubAppConfiguration configuration = buildConfiguration(almSettingDto.getAppId(), almSettingDto.getClientId(),\n      almSettingDto.getClientSecret(), almSettingDto.getPrivateKey(), almSettingDto.getUrl());\n\n    githubApplicationClient.checkApiEndpoint(configuration);\n    return githubApplicationClient.findMissingAppPermissions(configuration, requiredPermissions);\n  }\n\n  private GithubAppConfiguration buildConfiguration(@Nullable String applicationId, @Nullable String clientId, String clientSecret, String privateKey,\n    @Nullable String url) {\n    long appId;\n    try {\n      appId = Long.parseLong(Optional.ofNullable(applicationId).orElseThrow(() -> new IllegalArgumentException(\"Missing appId\")));\n    } catch (NumberFormatException e) {\n      throw new IllegalArgumentException(\"Invalid appId; \" + e.getMessage());\n    }\n    if (isBlank(clientId)) {\n      throw new IllegalArgumentException(\"Missing Client Id\");\n    }\n    if (isBlank(getDecryptedSettingValue(clientSecret))) {\n      throw new IllegalArgumentException(\"Missing Client Secret\");\n    }\n    return new GithubAppConfiguration(appId, getDecryptedSettingValue(privateKey), url);\n  }\n\n  private String getDecryptedSettingValue(String setting) {\n    if (StringUtils.isNotEmpty(setting) && encryption.isEncrypted(setting)) {\n      return encryption.decrypt(setting);\n    }\n    return setting;\n  }\n}\n","sourceCodeStart":81,"sourceCodeEnd":114,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-alm-client/src/main/java/org/sonar/alm/client/github/GithubGlobalSettingsValidator.java#L81-L114","documentation":"buildConfiguration requires a non-blank OAuth Client Id when validating GitHub global settings. If the clientId setting is null or blank, this IllegalArgumentException is thrown. GitHub bindings need the Client Id to support user-access-token based features.","triggerScenarios":"Calling configuration(...) with a null/empty/whitespace clientId while other fields are set — e.g. the setting was never saved or was cleared during an upgrade/import.","commonSituations":"Partial configuration where only appId and private key were entered; configuration-as-code export missing the clientId; secret management clearing non-secret settings; user confusion between App ID and Client Id fields.","solutions":["Enter the Client Id from GitHub App settings (About section) in the SonarQube GitHub configuration and save.","If using configuration-as-code, add the clientId property to the provisioning definition.","Verify the saved settings with GET api/settings/values?keys=sonar.auth.github.clientId.secured,sonar.auth.github.clientId.","Distinguish Client Id (string like Iv1.x) from the numeric App ID; each field needs its own value."],"exampleFix":"// before (settings map)\n{ \"sonar.auth.github.appId\": \"123456\", \"sonar.auth.github.clientSecret.secured\": \"***\" } // clientId missing\n// after\n{ \"sonar.auth.github.appId\": \"123456\", \"sonar.auth.github.clientId\": \"Iv1.8f2a9c1b\", \"sonar.auth.github.clientSecret.secured\": \"***\" }","handlingStrategy":"validation","validationCode":"// check required settings before invoking the validator\nif (clientId == null || clientId.isBlank()) throw new IllegalArgumentException(\"sonar.auth.github.clientId must be set\");\nif (clientSecret == null || clientSecret.isBlank()) throw new IllegalArgumentException(\"sonar.auth.github.clientSecret.secured must be set\");","typeGuard":"function hasClientId(config) { return typeof config.clientId === 'string' && config.clientId.trim().length > 0; }","tryCatchPattern":"try { validator.configuration(appId, clientId, secret, key, url); } catch (IllegalArgumentException e) { if (\"Missing Client Id\".equals(e.getMessage())) { markSettingRequired(\"sonar.auth.github.clientId\"); } throw e; }","preventionTips":["Include clientId in configuration-as-code exports/imports","Validate all required GitHub settings in one pre-save pass","Do not clear non-secret settings when rotating secrets","Differentiate App ID (numeric) and Client Id (Iv1.x) fields in the UI"],"tags":["github","validation","missing-field","alm-binding"],"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"}