SonarSource/sonarqube · warning

Cannot mint a GitHub installation token: project '{}' has no

Error message

Cannot mint a GitHub installation token: project '{}' has no repository configured on its DevOps Platform binding

What it means

GithubInstallationTokenProviderImpl.mint logs this warning and returns Optional.empty() when the project's GitHub binding has no almRepo value — ProjectAlmSettingDto.getAlmRepo() is null or blank. The binding exists and is a GitHub App configuration, but no target repository was recorded, so the provider cannot resolve a GitHub App installation for the project.

Source

Thrown at server/sonar-webserver-common/src/main/java/org/sonar/server/common/almsettings/github/GithubInstallationTokenProviderImpl.java:97

        LOG.warn("Cannot mint a GitHub installation token: unknown project '{}'", safeProjectKey);
        return Optional.empty();
      }

      Optional<ProjectAlmSettingDto> projectAlmSetting = dbClient.projectAlmSettingDao().selectByProject(dbSession, project.get());
      if (projectAlmSetting.isEmpty()) {
        LOG.warn("Cannot mint a GitHub installation token: project '{}' is not bound to any DevOps Platform", safeProjectKey);
        return Optional.empty();
      }

      Optional<AlmSettingDto> almSetting = dbClient.almSettingDao().selectByUuid(dbSession, projectAlmSetting.get().getAlmSettingUuid());
      if (almSetting.isEmpty() || almSetting.get().getAlm() != ALM.GITHUB) {
        LOG.warn("Cannot mint a GitHub installation token: project '{}' is not bound to a GitHub App", safeProjectKey);
        return Optional.empty();
      }

      String almRepo = projectAlmSetting.get().getAlmRepo();
      if (almRepo == null || almRepo.isBlank()) {
        LOG.warn("Cannot mint a GitHub installation token: project '{}' has no repository configured on its DevOps Platform binding", safeProjectKey);
        return Optional.empty();
      }

      resolvedAlmSetting = almSetting.get();
      resolvedAlmRepo = almRepo;
    }

    // GitHub App calls below are network I/O, deliberately made outside the DbSession above: the
    // orchestrator mints a fresh token before every git operation (no caching, by design), so
    // holding a pooled DB connection for their duration would add unnecessary contention under load.
    return mint(projectKey, resolvedAlmSetting, resolvedAlmRepo);
  }

  private Optional<GithubInstallationToken> mint(String projectKey, AlmSettingDto almSetting, String almRepo) {
    String safeProjectKey = sanitizeForLog(projectKey);
    String safeAlmRepo = sanitizeForLog(almRepo);

    GithubAppConfiguration githubAppConfiguration;

View on GitHub (pinned to 184c821202)

Solutions

  1. Set the repository on the binding: POST api/alm_settings/set_github with project, almSetting and repositoryName (e.g. 'org/repo').
  2. Inspect the binding with GET api/alm_settings/get_binding?project=<key> and fill in the missing repository field.
  3. Update provisioning templates so repositoryName is always supplied when binding projects to GitHub.
  4. Skip token minting in CI for projects without a repo configured, handling the empty Optional gracefully.

Example fix

// before
POST api/alm_settings/set_github -d project=my-app -d almSetting=github-company  (no repositoryName)
// after
POST api/alm_settings/set_github -d project=my-app -d almSetting=github-company -d repositoryName=org/my-app
Defensive patterns

Strategy: validation

Validate before calling

# Ensure repositoryName is set on the binding
REPO=$(curl -s -u "$TOKEN:" "$SQ_URL/api/alm_settings/get_binding?project=$KEY" | jq -r '.repository // empty')
[ -n "$REPO" ] || { echo "Binding has no repository; call set_github with repositoryName" >&2; exit 1; }

Prevention

When it happens

Trigger: Project bound to a GitHub ALM setting without specifying repositoryName (set_github called without repositoryName, or the binding's repo field later cleared).

Common situations: Provisioning script called set_github with only project and almSetting parameters; binding created via import/migration that didn't carry the repository field; repo removed intentionally but token minting still invoked by CI.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/b46361949aeca51c. Report an issue: GitHub.