permissions-dispatcher/PermissionsDispatcher · error · DuplicatedValueException
$value is duplicated in '${e.simpleString()}()' annotated wi
Error message
$value is duplicated in '${e.simpleString()}()' annotated with '@${annotation.simpleName}' What it means
Thrown by checkDuplicatedValue in Validators.kt:41. When multiple methods in one annotated class request the exact same permission set via @NeedsPermission (or @OnPermissionDenied etc.), the processor detects the duplicate sorted permissionValue list and throws DuplicatedValueException. Each permission combination must map to a single method so generated dispatch code stays unambiguous.
Source
Thrown at processor/src/main/kotlin/permissions/dispatcher/processor/util/Validators.kt:41
val type = element.asType()
try {
return units.first { type.isSubtypeOf(it.getTargetType()) }
} catch (ex: NoSuchElementException) {
throw WrongClassException(type)
}
}
/**
* Checks the elements in the provided list annotated with an annotation against duplicate values.
* <p>
* Raises an exception if any annotation value is found multiple times.
*/
fun <A : Annotation> checkDuplicatedValue(items: List<ExecutableElement>, annotationClass: Class<A>) {
val allItems: HashSet<List<String>> = hashSetOf()
items.forEach {
val permissionValue = it.getAnnotation(annotationClass).permissionValue().sorted()
if (allItems.contains(permissionValue)) {
throw DuplicatedValueException(permissionValue, it, annotationClass)
} else {
allItems.add(permissionValue)
}
}
}
/**
* Checks the elements in the provided list for elements.
* <p>
* Raises an exception if it doesn't contain any elements.
*/
fun <A : Annotation> checkNotEmpty(items: List<ExecutableElement>, rpe: RuntimePermissionsElement, annotationClass: Class<A>) {
if (items.isEmpty()) {
throw NoAnnotatedMethodsException(rpe, annotationClass)
}
}
/**View on GitHub (pinned to 74b532bf1f)
Solutions
- Remove or rename the duplicated annotation so only one method requests that exact permission set.
- Differentiate the methods by giving them distinct permission lists.
- Merge the duplicated methods into a single method called from both call sites.
Example fix
// before
@NeedsPermission(Manifest.permission.CAMERA)
fun showCamera() { }
@NeedsPermission(Manifest.permission.CAMERA)
fun openCamera() { }
// after
@NeedsPermission(Manifest.permission.CAMERA)
fun showCamera() { } // single method; call showCamera() from both places Defensive patterns
Strategy: validation
Validate before calling
val perms = mapOf(
"showCamera" to listOf(CAMERA),
"openGallery" to listOf(READ_MEDIA_IMAGES)
)
require(perms.values.toSet().size == perms.size) { "duplicate permission sets" } Try / catch
try {
buildProject()
} catch (e: CompilationError) {
logger.error("Duplicate @NeedsPermission values: give each method a unique permission set", e)
} Prevention
- One method per unique permission combination.
- Name methods after the permission set they request.
- Review diff when copy-pasting annotated methods.
When it happens
Trigger: Two methods in the same @RuntimePermissions class are annotated with identical permission arrays, e.g. two methods both @NeedsPermission(Manifest.permission.CAMERA), or same set in different order (order-insensitive because values are sorted before comparison).
Common situations: Copy-pasting an annotated method and forgetting to change its permissions; two overloads annotated with the same permissions; merging branches that each added a method for the same permission.
Related errors
- '${TypeName.get(type)}' can't be annotated with '@RuntimePer
- Annotated class '${rpe.inputClassName}' doesn't have any met
- Method '${e.simpleString()}()' annotated with '@${annotation
- Method '${e.simpleString()}()' must specify return type 'voi
- Method '${e.simpleString()}()' must not have any 'throws' de
AI-assisted analysis of permissions-dispatcher/PermissionsDispatcher@74b532bf1f (2026-09-08).
Data as JSON: /api/errors/f3af517a2db3a648.
Report an issue: GitHub.