{"record":{"id":"88c24ed1ee9e4f0b","repo":"phalcon/cphalcon","slug":"the-validator-scope-is-not-valid","errorCode":null,"errorMessage":"The validator scope is not valid","messagePattern":"The validator scope is not valid","errorType":"exception","errorClass":"Phalcon\\Filter\\Validation\\Exceptions\\InvalidValidatorScope","httpStatus":null,"severity":"error","filePath":"phalcon/Filter/Validation.zep","lineNumber":696,"sourceCode":"                 */\n                if this->preChecking(field, validator) {\n                    continue;\n                }\n\n                /**\n                 * Check if the validation must be canceled if this validator fails\n                 */\n                if validator->validate(this, field) === false {\n                    if validator->getOption(\"cancelOnFail\") {\n                        break;\n                    }\n                }\n            }\n        }\n\n        for scope in combinedFieldsValidators {\n            if unlikely typeof scope != \"array\" {\n                throw new InvalidValidatorScope();\n            }\n\n            let field     = scope[0],\n                validator = scope[1];\n\n            if unlikely typeof validator != \"object\" {\n                throw new InvalidValidator();\n            }\n\n            /**\n             * Call internal validations, if it returns true, then skip the\n             * current validator\n             */\n            if this->preChecking(field, validator) {\n                continue;\n            }\n\n            /**","sourceCodeStart":678,"sourceCodeEnd":714,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Filter/Validation.zep#L678-L714","documentation":"Combined-field validators (subclasses of AbstractCombinedFieldsValidator registered with an array of fields, e.g. Uniqueness over ['email','domain']) are stored as scopes: [fieldArray, validator]. During validate(), InvalidValidatorScope is thrown when a combined-fields entry is not an array — the internal structure was corrupted, since add() only ever appends well-formed pairs.","triggerScenarios":"A subclass of Validation assigning $this->combinedFieldsValidators = '...' or pushing a non-array entry; unserializing a cached validation object whose scope arrays were lost; third-party code mutating the protected property directly.","commonSituations":"Custom Validation subclasses that rebuild the combined validator list manually; session/cache serialization of validation state. Not reachable through the public add()/rule()/setValidators() API.","solutions":["Do not write combinedFieldsValidators directly — register combined validators through add(['field1','field2'], $combinedValidator)","In subclasses, append with the same [array $fields, ValidatorInterface $validator] tuple shape","Rebuild cached/serialized validation objects instead of restoring corrupted state"],"exampleFix":"// before\nclass MyValidation extends Validation\n{\n    public function init()\n    {\n        $this->combinedFieldsValidators[] = 'userUniqueness'; // string -> throws later\n    }\n}\n\n// after\n$this->add(['email', 'domain'], new Uniqueness());","handlingStrategy":"validation","validationCode":"// before validating on a hand-built/subclassed Validation, sanity-check the scopes:\n$ref = new ReflectionProperty($validation, 'combinedFieldsValidators');\nforeach ($ref->getValue($validation) as $scope) {\n    if (!is_array($scope)) {\n        throw new RuntimeException('Corrupt combined-fields scope: expected [fields, validator] array');\n    }\n}","typeGuard":"function scopeIsWellFormed($scope): bool\n{\n    return is_array($scope) && isset($scope[0], $scope[1]);\n}","tryCatchPattern":"use Phalcon\\Filter\\Validation\\Exceptions\\InvalidValidatorScope;\ntry {\n    $messages = $v->validate($data);\n} catch (InvalidValidatorScope $e) {\n    // internal state corrupt: rebuild the validation object from definitions\n    $v = $this->buildValidation();\n    $messages = $v->validate($data);\n}","preventionTips":["Register combined-field validators only via add(['f1','f2'], $validator) — never write the scope list by hand","Avoid serializing/caching Validation instances; rebuild them per request"],"tags":["phalcon","validation","combined-fields","state-corruption"],"backgroundTag":"malformed-validation-rules","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}