{"record":{"id":"472baa4185fe889c","repo":"apache/beam","slug":"found-two-matching-allowlist-classes-allowlistclass-and-cls","errorCode":null,"errorMessage":"Found two matching allowlist classes ${allowlistClass} and ${cls}","messagePattern":"Found two matching allowlist classes (.+?) and (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java","lineNumber":541,"sourceCode":"                          }\n                          return AllowedClass.create(\n                              className, allowedBuilderMethods, allowedConstructorMethods);\n                        })\n                    .collect(Collectors.toList());\n      }\n      return AllowList.create(version, allowedClasses);\n    }\n\n    public abstract String getVersion();\n\n    public abstract List<AllowedClass> getAllowedClasses();\n\n    public AllowedClass getAllowedClass(String className) {\n      AllowedClass allowlistClass = null;\n      for (AllowedClass cls : getAllowedClasses()) {\n        if (cls.isAllowedClass(className)) {\n          if (allowlistClass != null) {\n            throw new IllegalArgumentException(\n                \"Found two matching allowlist classes \" + allowlistClass + \" and \" + cls);\n          }\n          allowlistClass = cls;\n        }\n      }\n      if (allowlistClass == null) {\n        throw new UnsupportedOperationException(\n            \"The provided allow list does not enable expanding a transform class by the name \"\n                + className\n                + \".\");\n      }\n      return allowlistClass;\n    }\n\n    static AllowList create(String version, List<AllowedClass> allowedClasses) {\n      if (allowedClasses == null) {\n        allowedClasses = new ArrayList<>();\n      }","sourceCodeStart":523,"sourceCodeEnd":559,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/expansion-service/src/main/java/org/apache/beam/sdk/expansion/service/JavaClassLookupTransformProvider.java#L523-L559","documentation":"getAllowedClass scans the allowlist for a class matching the requested name (or assignable type) and found two distinct AllowedClass entries that both match. The allowlist itself is at fault: it declares overlapping/ambiguous entries (e.g. both a concrete class and an assignable supertype), so the lookup cannot choose one deterministically.","triggerScenarios":"Allowlist contains duplicate className entries, or two entries whose isAllowedClass both match the requested class (e.g. 'org.example.Foo' and 'org.example.*' both defined).","commonSituations":"Merging two allowlist files with overlapping packages; adding a specific class already covered by a wildcard; auto-generated config duplication.","solutions":["Remove duplicate/overlapping entries so each class matches exactly one allowlist entry.","Keep wildcard and specific entries mutually exclusive.","Deduplicate allowedClasses at generation time before feeding the service.","Identify the two conflicting entries from the message and drop the redundant one."],"exampleFix":"# before\nallowedClasses:\n  - className: org.example.*\n  - className: org.example.Foo\n# after\nallowedClasses:\n  - className: org.example.*","handlingStrategy":"validation","validationCode":"Set<String> seen = new HashSet<>();\nfor (AllowedClass ac : provider.getAllowedClasses()) {\n  if (!seen.add(ac.toString())) throw new IllegalStateException(\"Duplicate allowlist entry: \" + ac);\n}","typeGuard":"boolean isUnambiguous(AllowList list, String className) { return list.getAllowedClasses().stream().filter(c -> c.isAllowedClass(className)).count() <= 1; }","tryCatchPattern":"try { AllowedClass ac = provider.getAllowedClass(className); } catch (IllegalArgumentException e) { log.error(\"Ambiguous allowlist: {}\", e.getMessage()); throw new ConfigConflictException(e); }","preventionTips":["Run a pre-flight ambiguity check on startup","Prefer a single wildcard over wildcard+specific pairs","Deduplicate auto-generated allowlists before deploy","Review merged allowlist files for overlap"],"tags":["configuration","ambiguity","allowlist"],"backgroundTag":"conflicting-config-options","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}