{"record":{"id":"37279662115a6ae7","repo":"passbolt/passbolt_api","slug":"invalid-validation-ruleset","errorCode":null,"errorMessage":"Invalid validation ruleset.","messagePattern":"Invalid validation ruleset\\.","errorType":"http","errorClass":"InternalErrorException","httpStatus":500,"severity":"error","filePath":"plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryPrivateKeyPasswordsTable.php","lineNumber":218,"sourceCode":"            $f = strtoupper(str_replace(' ', '', $data['recipient_fingerprint']));\n            $data['recipient_fingerprint'] = $f;\n        }\n    }\n\n    /**\n     * @param \\App\\Utility\\UserAccessControl $uac user access control\n     * @param array $passwords user provided data\n     * @param string $validationRules ruleset\n     * @throws \\App\\Error\\Exception\\CustomValidationException if data doesn't validate\n     * @return array<\\Passbolt\\AccountRecovery\\Model\\Entity\\AccountRecoveryPrivateKeyPassword> array of entities\n     */\n    public function buildAndValidateEntities(\n        UserAccessControl $uac,\n        array $passwords,\n        string $validationRules = 'default'\n    ): array {\n        if (!in_array($validationRules, ['default', 'rotateKeys'])) {\n            throw new InternalErrorException('Invalid validation ruleset.');\n        }\n\n        foreach ($passwords as $i => $entity) {\n            $passwords[$i]['created_by'] = $uac->getId();\n            $passwords[$i]['modified_by'] = $uac->getId();\n        }\n\n        $accessibleFields = [\n            'recipient_fingerprint' => true,\n            'recipient_foreign_model' => true,\n            'data' => true,\n            'created_by' => true,\n            'modified_by' => true,\n        ];\n\n        // Private key id should only be set when rotating keys\n        // Otherwise passwords are created with the keys during setup or user settings change\n        if ($validationRules === 'rotateKeys') {","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/AccountRecovery/src/Model/Table/AccountRecoveryPrivateKeyPasswordsTable.php#L200-L236","documentation":"An InternalErrorException thrown when buildAndValidateEntities receives a $validationRules argument other than 'default' or 'rotateKeys'. This indicates a programming error in server code calling the table with an unsupported ruleset name, not user input.","triggerScenarios":"Internal service code passes a wrong ruleset string (typo, renamed option after refactor, or a version-mismatched plugin calling an older/newer signature).","commonSituations":"Custom plugins or forks calling the table method directly; code merged across EE versions where the 'rotateKeys' option was added or renamed; copy-pasted call sites using stale string constants.","solutions":["Fix the caller to pass 'default' or 'rotateKeys'.","Search the codebase for buildAndValidateEntities call sites using other strings.","If a new ruleset is genuinely needed, add it to the whitelist in the table method.","Ensure plugin versions are consistent with the core after an upgrade."],"exampleFix":"// before\n$table->buildAndValidateEntities($uac, $passwords, 'rotation');\n// after\n$table->buildAndValidateEntities($uac, $passwords, 'rotateKeys');","handlingStrategy":"validation","validationCode":"const RULESETS = ['default','rotateKeys'];\nif (!RULESETS.includes(validationRules)) throw new Error(`ruleset must be one of ${RULESETS.join(', ')}`);","typeGuard":"function isValidationRuleset(v) { return v === 'default' || v === 'rotateKeys'; }","tryCatchPattern":"try { $entities = $table->buildAndValidateEntities($uac, $passwords, $rules); } catch (InternalErrorException $e) { if ($e->getMessage() === 'Invalid validation ruleset.') { $rules = 'default'; $entities = $table->buildAndValidateEntities($uac, $passwords, $rules); } else { throw $e; } }","preventionTips":["Use class constants instead of raw strings for ruleset names.","Search call sites after renaming a ruleset.","Add a unit test covering both allowed values.","Keep plugin and core versions aligned."],"tags":["internal-error","validation-rules","account-recovery"],"backgroundTag":"invalid-enum-value","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"}