passbolt/passbolt_api · error · ConflictException
A subscription key is already present.
Error message
A subscription key is already present.
What it means
assertNotAlsoPro's second check: if the Subscriptions table already contains a row, creating another subscription key is rejected with ConflictException. The create endpoint only works on a clean instance with no stored subscription record.
Solutions
- Delete the existing subscription via the DELETE /edition/subscriptions endpoint, then create the new one
- Inspect the subscriptions table and remove stale records if the endpoint is unavailable
- Make create requests idempotent in automation (check before POST)
Example fix
// before
await api.post('/edition/subscriptions', {data: key}); // 409 when a key exists
// after
await api.delete('/edition/subscriptions');
await api.post('/edition/subscriptions', {data: key}); Defensive patterns
Strategy: validation
Validate before calling
const subs = await api.get('/edition/subscriptions');
if (subs.body.length > 0) { /* delete existing key first or skip create */ } Type guard
function hasExistingSubscription(subs: {length: number}): boolean { return subs.length > 0; } Try / catch
try {
await api.post('/edition/subscriptions', {data: key});
} catch (e) {
if (e.status === 409) { /* a key row exists: DELETE then re-create */ }
} Prevention
- Check for existing subscription rows before create calls
- Clean stale subscription records in reused test environments
- Guard against double-submission in UIs/scripts
When it happens
Trigger: POSTing a subscription key when any row exists in the Passbolt/Subscription.Subscriptions table, even if the edition is not yet PRO (e.g. a stale or legacy key record).
Common situations: Re-importing after a partial upgrade; leftover subscription row from a previous trial; test environment reused without clearing the subscriptions table; double-submitted create request.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- The instance is already on PRO.
- The resource could not be created due to a uniqueness…
- $e->getMessage() (from SubscriptionException)
- $e->getMessage() (from SubscriptionSignatureException)
- Only administrators can update the subscription details.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/ac84b6332093d09f.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/Edition/src/Controller/EditionSubscriptionsCreateController.php:76
$this->success(__('The subscription was created.'), $keyDto->toArray());
}
/**
* Rejects with HTTP 409 if the instance is already on PRO or already has a
* persisted subscription row.
*
* @return void
* @throws \Cake\Http\Exception\ConflictException
*/
private function assertNotAlreadyPro(): void
{
if ((new EditionGetService())->get()->isPro()) {
throw new ConflictException(__('The instance is already on PRO.'));
}
$subscriptions = $this->fetchTable('Passbolt/Subscription.Subscriptions');
if ($subscriptions->find()->count() > 0) {
throw new ConflictException(__('A subscription key is already present.'));
}
}
}
View on GitHub (pinned to 31c1bbc10f)