xpipe-io/xpipe · error · IllegalArgumentException
Scope ${scope} is not supported
Error message
Scope ${scope} is not supported What it means
MultiPrincipalSecret.with(secret, scope) re-encrypts the secret for a given DataStoreAccessScope, but only scopes for which supportsScopeEncryption(scope) is true are supported. Passing any other scope throws this IllegalArgumentException. It prevents silently producing a secret that cannot be used for that scope.
Source
Thrown at app/src/main/java/io/xpipe/app/secret/MultiPrincipalSecret.java:181
public static MultiPrincipalSecret of(SecretValue internalSecret, Set<EncryptionPrincipal> principals) {
for (EncryptionPrincipal principal : principals) {
if (!principal.isAccessible()) {
throw new IllegalArgumentException("Principal " + principal.getName() + " is not accessible");
}
}
var l = new ArrayList<Entry>();
for (EncryptionPrincipal principal : principals) {
var enc = AesSecretValue.encrypt(internalSecret.getSecret(), principal.getSecretKey());
l.add(new Entry(principal, enc.getEncryptedValue(), 1, EncryptionToken.of(principal)));
}
return new MultiPrincipalSecret(l, internalSecret.inPlace());
}
public MultiPrincipalSecret with(InPlaceSecretValue secret, DataStoreAccessScope scope) {
if (!supportsScopeEncryption(scope)) {
throw new IllegalArgumentException("Scope " + scope + " is not supported");
}
var secretUnchanged = secret == null || Arrays.equals(secret.getSecret(), this.secret.getSecret());
if (secretUnchanged && getScope().equals(scope) && isScopeValid()) {
return this;
}
var iteration = getMaxIteration();
var l = new ArrayList<Entry>();
for (EncryptionPrincipal principal : scope.getPrincipals()) {
var existingEntry = entries.stream()
.filter(entry -> entry.getPrincipal().equals(principal))
.findFirst();
// Keep existing entry if possible if not accessible
if (!principal.isAccessible()) {
if (existingEntry.isPresent()) {
l.add(existingEntry.get());View on GitHub (pinned to d85ca821ba)
Solutions
- Check supportsScopeEncryption(scope) before calling with() and handle unsupported scopes separately
- Use the scope instance obtained from the same store/secret API rather than a hand-built one
- Update code to a supported scope mapping after API changes
Example fix
// before
return secret.with(newSecret, scope);
// after
if (!secret.supportsScopeEncryption(scope)) {
return secret; // or handle unsupported scope
}
return secret.with(newSecret, scope); Defensive patterns
Strategy: validation
Validate before calling
if (!secret.supportsScopeEncryption(scope)) {
throw new IllegalArgumentException("Scope " + scope + " not supported");
} Try / catch
try { return secret.with(newSecret, scope); } catch (IllegalArgumentException e) { if (e.getMessage().contains("is not supported")) { /* handle unsupported scope */ } else throw e; } Prevention
- Only pass scopes sourced from the same store API
- Consult supportsScopeEncryption() before updates
- Map legacy scopes explicitly after refactors
When it happens
Trigger: Calling with(secret, scope) (directly or via withUpdatedPrincipals) with a scope value not covered by supportsScopeEncryption — e.g. a scope enum/constant outside the supported set for this secret type.
Common situations: Passing the wrong DataStoreAccessScope constant after a refactor; constructing secrets for a store type whose scope is not encryptable; migrating code between scope enums.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Principal ${name} is not accessible
- No secret available to encrypt
- Secret is not accessible
- Unable to parse or decrypt secret
- Unknown principal " + pr
AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06).
Data as JSON: /api/errors/935de4e771ddbeb6.
Report an issue: GitHub.