{"record":{"id":"3a06ed0bbae8f1c7","repo":"cakephp/cakephp","slug":"a-validation-rule-with-the-name-name-already-exists","errorCode":null,"errorMessage":"A validation rule with the name `{$name}` already exists","messagePattern":"A validation rule with the name `(.+?)` already exists","errorType":"exception","errorClass":"CakeException","httpStatus":null,"severity":"error","filePath":"src/Validation/ValidationSet.php","lineNumber":161,"sourceCode":"     *\n     * ```\n     *      $set\n     *          ->add('notBlank', ['rule' => 'notBlank'])\n     *          ->add('inRange', ['rule' => ['between', 4, 10])\n     * ```\n     *\n     * @param string $name The name under which the rule should be set\n     * @param \\Cake\\Validation\\ValidationRule|array $rule The validation rule to be set\n     * @return $this\n     * @throws \\Cake\\Core\\Exception\\CakeException If a rule with the same name already exists\n     */\n    public function add(string $name, ValidationRule|array $rule)\n    {\n        if (!($rule instanceof ValidationRule)) {\n            $rule = new ValidationRule($rule);\n        }\n        if (array_key_exists($name, $this->_rules)) {\n            throw new CakeException(\"A validation rule with the name `{$name}` already exists\");\n        }\n        $this->_rules[$name] = $rule;\n\n        return $this;\n    }\n\n    /**\n     * Removes a validation rule from the set\n     *\n     * ### Example:\n     *\n     * ```\n     *      $set\n     *          ->remove('notBlank')\n     *          ->remove('inRange')\n     * ```\n     *\n     * @param string $name The name under which the rule should be unset","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/cakephp/cakephp/blob/1128eba9b09f1946df684811350e26f2cef68fac/src/Validation/ValidationSet.php#L143-L179","documentation":"ValidationSet manages named validation rules for a field. ValidationSet::add() refuses to overwrite an existing rule name and throws CakeException when the name already exists in its rules. Rules must be added once with unique names per field.","triggerScenarios":"Calling add('notBlank', ...) twice on the same ValidationSet, or offsetSet[] assignment reusing an existing rule name for the same field — often when building validators programmatically or in loops.","commonSituations":"Conditionally adding rules in loops that execute twice; plugin/provider code and app code both adding the same rule name to a field; validators reconfigured at runtime without removing existing rules first.","solutions":["Check has($name) (or offsetExists) before adding and skip or rename the rule","Call remove($name) first if replacement is intended","Ensure loops/conditional logic don't add the same rule twice","Use unique rule names per field (e.g. prefix custom rules)"],"exampleFix":"// before\n$set->add('notBlank', ['rule' => 'notBlank']);\n$set->add('notBlank', ['rule' => 'notBlank']); // throws\n// after\nif (!$set->has('notBlank')) {\n    $set->add('notBlank', ['rule' => 'notBlank']);\n}","handlingStrategy":"try-catch","validationCode":"if ($set->has($name)) {\n    $set->remove($name); // or skip\n}\n$set->add($name, $rule);","typeGuard":"function canAddRule(Cake\\Validation\\ValidationSet $set, string $name): bool\n{\n    return !$set->has($name);\n}","tryCatchPattern":"try {\n    $set->add($name, $rule);\n} catch (Cake\\Core\\Exception\\CakeException $e) {\n    if (str_contains($e->getMessage(), 'already exists')) {\n        $set->remove($name);\n        $set->add($name, $rule); // replace intentionally\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Guard with has()/offsetExists before adding rules","Make rule names unique per field, especially in plugin + app combinations","Avoid re-running rule-registration code (loops, repeated bootstrap)","Call remove() explicitly when replacement is intended"],"tags":["validation","duplicate-key","cakephp"],"backgroundTag":"file-already-exists","analyzedSha":"1128eba9b09f1946df684811350e26f2cef68fac","analyzedAt":"2026-09-12T12:07:00.388Z","contentChangedAt":"2026-09-12T12:07:00.388Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}