{"record":{"id":"62405d5267c3e782","repo":"passbolt/passbolt_api","slug":"exception-getmessage-dynamic-from-wrapped-62405d","errorCode":null,"errorMessage":"$exception->getMessage() (dynamic, from wrapped CustomValidationException)","messagePattern":"\\$exception->getMessage\\(\\) \\(dynamic, from wrapped CustomValidationException\\)","errorType":"validation","errorClass":"CustomValidationException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php","lineNumber":249,"sourceCode":"        }\n\n        return $privateKeyEntity;\n    }\n\n    /**\n     * @return array<\\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryPrivateKeyPassword> array of AccountRecoveryPrivateKeyPasswords\n     */\n    public function buildPasswordEntitiesFromDataOrFail(): array\n    {\n        $passwordsData = $this->data['account_recovery_private_key']['account_recovery_private_key_passwords'] ?? [];\n        try {\n            $service = new AccountRecoveryPrivateKeyPasswordsValidationService();\n            $publicKey = $this->organizationPolicy->account_recovery_organization_public_key->armored_key;\n\n            return $service->buildPasswordEntitiesFromDataOrFail($this->uac, $passwordsData, $publicKey);\n        } catch (CustomValidationException $exception) {\n            // re-wrap errors under parent object\n            throw new CustomValidationException($exception->getMessage(), [\n                'account_recovery_user_setting' => $exception->getErrors(),\n            ]);\n        }\n    }\n\n    /**\n     * @return bool true if the account_recovery_private_key data is set\n     */\n    protected function isPrivateKeyProvided(): bool\n    {\n        return isset($this->data['account_recovery_private_key']);\n    }\n\n    /**\n     * @return bool true if the account_recovery_private_key.account_recovery_private_key_passwords data is set\n     */\n    protected function arePasswordsProvided(): bool\n    {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Service/AccountRecoveryUserSettings/AccountRecoveryUserSettingsSetService.php#L231-L267","documentation":"buildPasswordEntitiesFromDataOrFail() wraps a CustomValidationException coming from AccountRecoveryPrivateKeyPasswordsValidationService and re-throws it with the original message but errors re-nested under 'account_recovery_user_setting' for consistent response shape. The message is dynamic from the wrapped exception.","triggerScenarios":"Key password entries failing validation: not a string, not valid base64/encrypted payload, failing to decrypt against the organization public key, or wrong structure in account_recovery_private_key_passwords.","commonSituations":"Client encrypting key passwords with the wrong recipient key or an outdated organization public key; payloads built for an older schema; corrupted base64 from encoding issues.","solutions":["Check nested errors under account_recovery_user_setting for the failing entry index","Re-encrypt the private key passwords with the current organization public key fetched from the server","Ensure each password is properly base64-encoded encrypted data per the API schema","Refresh the org policy cache so the client uses the latest organization public key"],"exampleFix":"// before\nencryptWith(oldOrgPublicKey, password)\n// after\nconst {armoredKey} = await orgPolicyGetService.getOrFail();\nencryptWith(armoredKey, password)","handlingStrategy":"try-catch","validationCode":"const {armored_key} = await getOrgPolicy(); // ensure passwords are encrypted to this key before submitting","typeGuard":"const areEncryptedPasswords = (arr) => Array.isArray(arr) && arr.every(p => typeof p === 'string' && /^[A-Za-z0-9+/=]+$/.test(p));","tryCatchPattern":"try { await setSettings(data); } catch (e) { if (e.body?.account_recovery_user_setting) showErrors(e.body.account_recovery_user_setting); }","preventionTips":["Encrypt key passwords with the current organization public key","Refetch org policy when keys are rotated","Base64-encode encrypted payloads exactly per schema"],"tags":["validation","encryption","account-recovery"],"backgroundTag":"schema-validation-failed","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}