phalcon/cphalcon · error · Phalcon\Acl\Exceptions\ForbiddenWildcard
The role name cannot be '*'
Error message
The role name cannot be '*'
What it means
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.
Source
Thrown at phalcon/Acl/Role.zep:26
* file that was distributed with this source code.
*/
namespace Phalcon\Acl;
use Phalcon\Acl\Exceptions\ForbiddenWildcard;
/**
* This class defines role entity and its description
*/
class Role extends AbstractElement implements RoleInterface
{
/**
* Phalcon\Acl\Role constructor
*/
public function __construct( string name, string description = null)
{
if unlikely name === "*" {
throw new ForbiddenWildcard("role");
}
let this->name = name,
this->description = description;
}
}
View on GitHub (pinned to b7419de9cd)
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
Example fix
// before
$acl->addRole(new \Phalcon\Acl\Role('*', 'matches everything'));
// after
$acl->addRole(new \Phalcon\Acl\Role('guest', 'default role'));
$acl->allow('guest', 'invoices', 'view'); Defensive patterns
Strategy: validation
Validate before calling
if ($name === '*') {
throw new InvalidArgumentException('Role name "*" is reserved by the ACL; choose a concrete name.');
}
$role = new \Phalcon\Acl\Role($name, $description); Type guard
function isValidAclRoleName(string $name): bool
{
return $name !== '*';
} Try / catch
try {
$role = new \Phalcon\Acl\Role($name);
} catch (\Phalcon\Acl\Exceptions\ForbiddenWildcard $e) {
// reserved wildcard reached the constructor; map to a user-facing error
throw new InvalidArgumentException('Invalid role name supplied', 0, $e);
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Headers have already been sent; cannot emit the response.
- No route matched the request.
- The request method is not allowed for the matched route.
- Invalid value for the accessList
- Object passed as componentName must implement Phalcon\Acl\Co
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/bad485622786eb45.
Report an issue: GitHub.