passbolt/passbolt_api · error · BadRequestException
A value for the theme should be provided.
Error message
A value for the theme should be provided.
What it means
Thrown by Gnupg::setSignKeyFromFingerprint when gnupg_addsignkey() fails for a key already present in the keyring, addressed by fingerprint. The key must exist in the keyring, hold a secret signing part, and match the supplied passphrase. The gnupg exception message is appended.
Solutions
- Confirm the fingerprint exists with `gpg --list-secret-keys --fingerprint`.
- Re-import the private signing key first, then call setSignKeyFromFingerprint.
- Verify the passphrase for that key.
- Check key expiry/revocation status.
- Ensure GNUPGHOME is correct and accessible to the PHP process.
Example fix
// before $gpg->setSignKeyFromFingerprint($oldFingerprint, $pass); // key no longer in keyring // after $fp = $gpg->importKeyIntoKeyring($privateArmoredKey); $gpg->setSignKeyFromFingerprint($fp, $correctPass);
Defensive patterns
Strategy: validation
Validate before calling
$out = shell_exec('GNUPGHOME=' . $home . ' gpg --list-secret-keys --with-colons ' . escapeshellarg($fingerprint));
if ($out === null || trim($out) === '') {
throw new InvalidArgumentException('No secret key in keyring for ' . $fingerprint);
}
Type guard
function isFingerprint(string $f): bool {
return (bool) preg_match('/^[0-9A-F]{40}$/i', str_replace(' ', '', $f));
}
Try / catch
try {
$gpg->setSignKeyFromFingerprint($fp, $pass);
} catch (\Cake\Core\Exception\Exception $e) {
$this->log('addsignkey failed for ' . $fp . ': ' . $e->getMessage());
throw new ServerKeyConfigurationException(previous: $e);
}
Prevention
- Check `gpg --list-secret-keys` before assuming the key is in the keyring.
- Re-import the key in the same process instead of trusting persistent keyrings.
- Track key rotation: update stored fingerprint and passphrase together.
- Test expiry/revocation status at startup.
When it happens
Trigger: Calling setSignKeyFromFingerprint($fingerprint, $passphrase) where the fingerprint is absent from the keyring, passphrase is wrong, or the key cannot sign (expired/revoked/no secret part).
Common situations: Stale fingerprint after key regeneration; keyring wiped (ephemeral CI containers); passphrase changed; fingerprint casing/whitespace mismatch.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Can not upgrade. Please upgrade to the latest 1.x version…
- Could not sign the text.
- The anonymous user id should be a UUID
- The key was not found in the keyring
- The OpenPGP server key defined in the config cannot be used…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/312e271d26b0295c.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltCe/AccountSettings/src/Controller/Themes/ThemesSelectController.php:37
use App\Controller\AppController;
use App\Error\Exception\ValidationException;
use Cake\Http\Exception\BadRequestException;
/**
* @property \Passbolt\AccountSettings\Model\Table\AccountSettingsTable $AccountSettings
*/
class ThemesSelectController extends AppController
{
/**
* Themes Select action
*
* @return void
*/
public function select()
{
$theme = $this->request->getData('value');
if (!isset($theme) || empty($theme)) {
throw new BadRequestException(__('A value for the theme should be provided.'));
}
/** @var \Passbolt\AccountSettings\Model\Table\AccountSettingsTable $accountSettingsTable */
$accountSettingsTable = $this->fetchTable('Passbolt/AccountSettings.AccountSettings');
try {
$setting = $accountSettingsTable->createOrUpdateSetting($this->User->id(), 'theme', $theme);
} catch (ValidationException $e) {
throw new BadRequestException(__('This is not a valid theme.'));
}
$this->success(__('The operation was successful.'), $setting);
}
}
View on GitHub (pinned to 31c1bbc10f)