cakephp/cakephp · error · CakeException
A rule with the name
Error message
A rule with the name `{$name}` already exists What it means
RulesChecker lets rules be registered under an optional name so they can be referenced later. checkName() enforces name uniqueness within the rules array; adding a second rule with an existing name throws CakeException to prevent silent overwrite of domain rules.
Solutions
- Remove the duplicate add call, or give one of the rules a distinct name.
- Ensure buildRules() runs exactly once per checker; make registration idempotent.
- If re-registration is intentional replacement, remove the old rule first or restructure so buildRules() is idempotent.
- Rename colliding rules in traits/base classes to reflect their owner, e.g. 'app.uniqueEmail' vs 'plugin.uniqueEmail'.
Example fix
// before
$rules->add($rules->isUnique(['email']), 'uniqueEmail');
$rules->add($rules->validCount('tags'), 'uniqueEmail'); // duplicate name
// after
$rules->add($rules->isUnique(['email']), 'uniqueEmail');
$rules->add($rules->validCount('tags'), 'validTagCount'); Defensive patterns
Strategy: try-catch
Validate before calling
// in Table::buildRules() — register each named rule exactly once
$ruleName = 'uniqueEmail';
if (!isset($registered[$ruleName])) {
$rules->add($rules->isUnique(['email']), $ruleName);
$registered[$ruleName] = true;
} Try / catch
try {
$rules->add($rules->isUnique(['email']), $ruleName);
} catch (\Cake\Core\Exception\CakeException $e) {
if (!str_contains($e->getMessage(), 'already exists')) {
throw $e; // different failure — rethrow
}
// named rule already registered; skip
} Prevention
- Register each named rule exactly once, in buildRules().
- Use owner-prefixed unique names when combining traits/inheritance (e.g. 'plugin.uniqueEmail').
- Never invoke buildRules() manually multiple times on the same checker.
- Document rule names in one place to avoid copy-paste collisions.
When it happens
Trigger: Calling $rules->add(..., 'uniqueEmail') twice in the same table's buildRules(); buildRules() running more than once (e.g. re-invoked via traits/subclasses) re-adding named rules; two parent classes/traits both adding a rule with the same name.
Common situations: Copy-pasting rule registrations between parent/child table classes with identical names; conditional rule-adding logic executed multiple times (e.g. in initialize() called repeatedly in tests); merging rule definitions from config where names collide.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Wrong checking mode:
- A validation rule with the name
- Argument 2 is expected to have a `repository` key that…
- Argument 2 is expected to match one of the…
- Argument ` ` must be an alphanumeric string
AI-assisted analysis of cakephp/cakephp@1128eba9b0 (2026-09-12).
Data as JSON: /api/errors/e21be9ec33cfe898.
Report an issue: GitHub.
Appendix: source
Thrown at src/Datasource/RulesChecker.php:424
} else {
$rule->setOptions($options)->setName($name);
}
return $rule;
}
/**
* Checks that a rule with the same name doesn't already exist
*
* @param string $name The name to check
* @param array<\Cake\Datasource\RuleInvoker> $rules The rules array to check
* @return void
* @throws \Cake\Core\Exception\CakeException
*/
protected function checkName(string $name, array $rules): void
{
if (array_key_exists($name, $rules)) {
throw new CakeException("A rule with the name `{$name}` already exists");
}
}
}
View on GitHub (pinned to 1128eba9b0)