{"record":{"id":"0ab94e3984440c10","repo":"SonarSource/sonarqube","slug":"the-0-key-matches-multiple-permission-template","errorCode":null,"errorMessage":"The \"{0}\" key matches multiple permission templates: {1}. A system administrator must update these templates so that only one of them matches the key.","messagePattern":"The \"(.+?)\" key matches multiple permission templates: (.+?)\\. A system administrator must update these templates so that only one of them matches the key\\.","errorType":"exception","errorClass":"TemplateMatchingKeyException","httpStatus":400,"severity":"error","filePath":"server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java","lineNumber":235,"sourceCode":"      case ComponentQualifiers.APP:\n        String appDefaultTemplateUuid = resolvedDefaultTemplates.getApplication().orElseThrow(\n          () -> new IllegalStateException(\"Failed to find default template for applications\"));\n        return dbClient.permissionTemplateDao().selectByUuid(dbSession, appDefaultTemplateUuid);\n      default:\n        throw new IllegalArgumentException(format(\"Qualifier '%s' is not supported\", qualifier));\n    }\n  }\n\n  private static void checkAtMostOneMatchForComponentKey(String componentKey, List<PermissionTemplateDto> matchingTemplates) {\n    if (matchingTemplates.size() > 1) {\n      StringBuilder templatesNames = new StringBuilder();\n      for (Iterator<PermissionTemplateDto> it = matchingTemplates.iterator(); it.hasNext();) {\n        templatesNames.append(\"\\\"\").append(it.next().getName()).append(\"\\\"\");\n        if (it.hasNext()) {\n          templatesNames.append(\", \");\n        }\n      }\n      throw new TemplateMatchingKeyException(MessageFormat.format(\n        \"The \\\"{0}\\\" key matches multiple permission templates: {1}.\"\n          + \" A system administrator must update these templates so that only one of them matches the key.\",\n        componentKey,\n        templatesNames.toString()));\n    }\n  }\n\n}\n","sourceCodeStart":217,"sourceCodeEnd":244,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-webserver-common/src/main/java/org/sonar/server/common/permission/PermissionTemplateService.java#L217-L244","documentation":"Permission templates can declare key patterns (project key regexes). When a component key matches more than one template, SonarQube cannot decide which applies, so PermissionTemplateService.checkAtMostOneMatchForComponentKey (invoked via findTemplate) throws this TemplateMatchingKeyException listing the conflicting template names.","triggerScenarios":"findTemplate is called for a component key and multiple permission templates have patterns matching that key, e.g. two templates both matching 'org:repo' or overlapping regexes like '.*' and '^org:.*'.","commonSituations":"A catch-all template ('.*') left in place alongside specific templates; duplicated templates after import/restore; pattern edits that broaden a template's regex over existing ones.","solutions":["Edit the conflicting templates' project key patterns so exactly one matches the key (as the message says, an administrator must do this).","Remove or narrow any catch-all '.*' template that overlaps specific templates.","List templates (api/permissions/templates) and check their patterns to identify the overlap."],"exampleFix":"// before\ntemplate A pattern: .*  |  template B pattern: ^my-project$\n\n// after\ntemplate A pattern: ^other-.*$  |  template B pattern: ^my-project$","handlingStrategy":"validation","validationCode":"// count matches before lookup\nlong matches = templates.stream()\n  .filter(t -> t.getProjectKeyPattern().matcher(componentKey).matches())\n  .count();\nif (matches > 1) throw new IllegalStateException(\"Key matches \" + matches + \" templates\");","typeGuard":null,"tryCatchPattern":"try { PermissionTemplateDto tpl = service.findTemplate(db, componentKey); } catch (TemplateMatchingKeyException e) { log.error(\"Fix overlapping template patterns: {}\", e.getMessage()); }","preventionTips":["Review project key patterns for overlap after any template edit or import.","Avoid broad catch-all patterns like '.*' alongside specific ones."],"tags":["permission-templates","regex-conflict","configuration"],"backgroundTag":"conflicting-config-options","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}