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

  1. Pick a concrete role name such as 'guest' or 'all' and construct the Role with it
  2. Validate dynamic role names before instantiation and reject '*' with your own error message
  3. 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

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


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/bad485622786eb45. Report an issue: GitHub.