{"record":{"id":"bad485622786eb45","repo":"phalcon/cphalcon","slug":"the-role-name-cannot-be","errorCode":null,"errorMessage":"The role name cannot be '*'","messagePattern":"The role name cannot be '\\*'","errorType":"exception","errorClass":"Phalcon\\Acl\\Exceptions\\ForbiddenWildcard","httpStatus":null,"severity":"error","filePath":"phalcon/Acl/Role.zep","lineNumber":26,"sourceCode":" * file that was distributed with this source code.\n */\n\nnamespace Phalcon\\Acl;\n\nuse Phalcon\\Acl\\Exceptions\\ForbiddenWildcard;\n\n/**\n * This class defines role entity and its description\n */\nclass Role extends AbstractElement implements RoleInterface\n{\n    /**\n     * Phalcon\\Acl\\Role constructor\n     */\n    public function __construct( string name, string description = null)\n    {\n        if unlikely name === \"*\" {\n            throw new ForbiddenWildcard(\"role\");\n        }\n\n        let this->name = name,\n            this->description = description;\n    }\n}\n","sourceCodeStart":8,"sourceCodeEnd":33,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Acl/Role.zep#L8-L33","documentation":"Phalcon\\Acl\\Role rejects the name '*' at construction time because the asterisk is a reserved wildcard in the ACL ('*' means 'any role' in allow/deny rules and role inheritance). Constructing a role named '*' would make access checks ambiguous, so the constructor fails fast with ForbiddenWildcard. The same rule applies symmetrically to components and anywhere a named ACL entity is created.","triggerScenarios":"Calling `new \\Phalcon\\Acl\\Role('*')` (with or without a description), or `$acl->addRole(new Role('*'))`. Any code that feeds dynamic data (config, DB, request input) into the Role constructor and lets the literal '*' through will hit it.","commonSituations":"Seeding roles from a config file where '*' was meant as a catch-all/default role; migrating from another ACL library in which '*' denoted 'any role'; generating role names from user or tenant data without sanitizing reserved characters.","solutions":["Pick a concrete role name such as 'guest' or 'all' and construct the Role with it","Validate dynamic role names before instantiation and reject '*' with your own error message","Express 'applies to every role' semantics via `$acl->allow('*', $component, $action)` or role inheritance instead of a literal '*' role"],"exampleFix":"// before\n$acl->addRole(new \\Phalcon\\Acl\\Role('*', 'matches everything'));\n// after\n$acl->addRole(new \\Phalcon\\Acl\\Role('guest', 'default role'));\n$acl->allow('guest', 'invoices', 'view');","handlingStrategy":"validation","validationCode":"if ($name === '*') {\n    throw new InvalidArgumentException('Role name \"*\" is reserved by the ACL; choose a concrete name.');\n}\n$role = new \\Phalcon\\Acl\\Role($name, $description);","typeGuard":"function isValidAclRoleName(string $name): bool\n{\n    return $name !== '*';\n}","tryCatchPattern":"try {\n    $role = new \\Phalcon\\Acl\\Role($name);\n} catch (\\Phalcon\\Acl\\Exceptions\\ForbiddenWildcard $e) {\n    // reserved wildcard reached the constructor; map to a user-facing error\n    throw new InvalidArgumentException('Invalid role name supplied', 0, $e);\n}","preventionTips":["Validate externally sourced role names at the trust boundary (config/DB/request) before ACL calls","Keep the list of valid role names in one constant/config and reject anything else early","Use ACL wildcard syntax ('*' in allow/deny) for 'any role' semantics — never as an entity name"],"tags":["acl","role","wildcard","validation"],"backgroundTag":"reserved-name-rejected","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}