Errors & exceptions
Warrant fails loudly. A typo in a stored rule, a missing context key, or a misconfigured schema throws rather than silently granting or denying. This is the catalogue.
When each error surfaces
Section titled “When each error surfaces”| Stage | What’s checked |
|---|---|
| Parse time | Rule syntax, binding consistency (WarrantSyntaxException) |
| Compile / validate time | Ability / condition / context-key names exist on the schema |
| Check time | Requested ability exists; required context present; user available |
| Boot / reflection | Schema registry uniqueness; condition method signatures |
Syntax errors → WarrantSyntaxException
Section titled “Syntax errors → WarrantSyntaxException”Thrown eagerly from the lexer/parser. Extends RuntimeException and carries
$source, $offset, $sourceLine, and $sourceColumn. The message includes the
line, column, and a caret:
Reserved word 'can' cannot be used as a name; expected an ability name. (line 1, column 21)
if is_self they can can ^Representative messages:
Unexpected character %s.Unterminated string literal.Invalid escape sequence "\%s"; only \' and \\ are allowed.Expected 'context' after '@'./Expected a context key after '@context'.Expected 'can' or 'cannot' after 'they'.Expected at least one 'they can ...' or 'they cannot ...' clause.Expected ')' to close the group./Expected ')' to close the condition arguments.Reserved word '%s' cannot be used as a name; expected %s.Expected a rule./Expected a single rule but found multiple.
Binding errors (also WarrantSyntaxException)
Section titled “Binding errors (also WarrantSyntaxException)”Cannot mix named and positional bindings.No binding provided for ":%s".More positional placeholders (?) than bindings provided.%d positional binding(s) were provided but never used.Binding(s) provided but never used: %s.
Validation errors → InvalidArgumentException
Section titled “Validation errors → InvalidArgumentException”Thrown when a rule set is validated/compiled against a schema:
Ability [%s] is not declared by the schema.Condition [%s] is not declared by the schema.Context key [%s] is not declared by the schema.
Attaching a denial message to a rule that has no theyCannot clause is also
rejected here — only a cannot rule may carry a withDenialMessage(). See
Denial messages.
fromRules / validateAll type-guard their inputs:
fromRules expects WarrantRule or WarrantRuleBuilder instances, got %s.validateAll expects WarrantRuleSet instances, got %s.
Condition / reflection errors → InvalidArgumentException
Section titled “Condition / reflection errors → InvalidArgumentException”Thrown lazily the first time a schema’s conditions are reflected:
Condition method [%s::%s] must not declare duplicate condition attributes.Condition method [%s::%s] cannot declare both #[TargetedCondition] and #[GlobalCondition].Condition method [%s::%s] must resolve to a non-empty condition key.Condition method [%s::%s] must accept exactly one [%s] parameter.— wrong context type or an extra parameter.Schema [%s] is a schema with no model and does not support targeted checks; use a no-target check instead.
Applying a condition
Section titled “Applying a condition”From the condition resolver:
BadMethodCallException—Condition [%s] is not defined on schema [%s].InvalidArgumentException—Condition [%s] on schema [%s] requires a target SQL id.(a targeted condition run with no target)
Context errors → InvalidArgumentException
Section titled “Context errors → InvalidArgumentException”Schema [%s] requires context key(s) [%s]; supply them at the check or via defaultContext().See Check-time context. Note the fail-open caveat: an optional key that’s absent doesn’t throw — it soft-falses its condition.
Registry errors → WarrantManager
Section titled “Registry errors → WarrantManager”InvalidArgumentException—Duplicate schema for schema key .../Duplicate schema for model ...(at boot)OutOfBoundsException—No Warrant schema registered for model [%s].OutOfBoundsException—No Warrant schema registered for schema key [%s].
Authorization failures → WarrantAuthorizationException
Section titled “Authorization failures → WarrantAuthorizationException”Thrown by authorize() when a check is
denied. It extends Illuminate\Auth\Access\AuthorizationException, so Laravel
renders it as HTTP 403 automatically.
public function __construct( string $message = 'This action is unauthorized.', ?WarrantDenialContext $denial = null,);
public readonly ?WarrantDenialContext $denial; // the diagnosed denial, or null for a generic denialThe $denial property carries a diagnosed denial-context data object (a plain
final readonly object under Warrant\, not an exception) describing why the
check failed:
WarrantGate— the requestedarray $abilities(normalized, wildcards resolved) andAbilityMatchMode $matchMode.WarrantDenialContext—$user,?Model $target,string $schema,array $context,WarrantGate $gate, the responsibleWarrantRule $rule(the matchingcannot), andarray $deniedAbilities.WarrantUngrantedContext— same fields minus$rule, witharray $ungrantedAbilitiesin place ofdeniedAbilities(the whole gate underANY; the missing subset underALL).
See Denial messages for attaching messages and the schema fallback hooks.
Middleware errors
Section titled “Middleware errors”See Middleware API. Unauthenticated or
unauthorized requests abort(403); misconfiguration throws
InvalidArgumentException.
Trait errors → LogicException
Section titled “Trait errors → LogicException”... requires an authenticated user or an explicit user instance.(scopes/helpers with no user)Model [%s] must return a WarrantSchema class string, got [%s].Schema [%s] must manage model [%s], got [%s].
Writer errors → LogicException
Section titled “Writer errors → LogicException”Thrown by toSyntax() when a rule can’t be rendered as inline DSL — use
toBoundSyntax() instead:
A constant boolean expression has no rule-language representation.Condition parameter of type %s cannot be written inline; use toBoundSyntax().NAN/INF cannot be written inline; use toBoundSyntax().Float %s requires exponent notation, unsupported inline; use toBoundSyntax().
Configuration & driver errors → RuntimeException
Section titled “Configuration & driver errors → RuntimeException”No Warrant rule resolver configured. Set warrant.rule_resolver to a class implementing Warrant\RuleResolver.Warrant ability selection does not support the [%s] database driver.(a driver other than PostgreSQL, MySQL/MariaDB, or SQLite for the per-row abilities column)
