GLPI Business Rules: No-Code Automation

GLPI business rules do not stop at the first match: the RuleTicket engine runs them all in ranking order and chains the output, so a generic rule can overwrite a specific one. A technical guide to the real evaluation model, the GLPI 11 operator codes, an audit SQL query and the matrix of which rule collection to use - with the field mistake that generates the most support tickets in maintenance.

Business rules are GLPI's native automation engine: with no code at all, they classify, assign and apply SLAs to every ticket. What the documentation rarely explains - and what generates the most support tickets when you maintain client GLPI estates - is not how to create a rule, but the evaluation model that decides which rule wins when two of them overlap. This guide starts where most tutorials stop: order, trigger condition and chaining.

The evaluation model almost nobody reads before their first rule

Every ticket business rule has the subtype RuleTicket and lives in the glpi_rules table. Three columns drive the behaviour:

  • ranking - the evaluation order. The engine reads in ascending order, from lowest to highest. The screen shows them top to bottom, but the number is what rules.
  • condition - when the rule fires: 1 on creation, 2 on update, 3 on both. A rule created for 1 only never re-evaluates when the ticket is edited later.
  • match - the logic between criteria: AND (all must match) or OR (any of them).

The detail that trips up most people: ticket rules do not stop at the first match. Unlike mail collector rules and inventory import rules, the RuleTicket engine walks through ALL active rules in ranking order and feeds the output of one as the input of the next. In other words, a generic rule with a higher ranking (evaluated later) can overwrite the assignment made by a specific rule that had already matched earlier.

The real anatomy: criteria, actions and operators

Every rule has three blocks. Criteria live in glpi_rulecriterias, actions in glpi_ruleactions:

  • Criterion = criteria (the field) + condition (the operator, numeric) + pattern (the expected value).
  • Action = action_type (assign, regex_result, append, fromuser, fromitem) + field (the field to change) + value.

The operator is a numeric code, not text - and picking the wrong one is the most common silent failure. The values in GLPI 11:

0  = is (exact match)
1  = is not
2  = contains
3  = does not contain
4  = begins with
5  = ends with
6  = regular expression (regex)
7  = regex does not match
8  = exists
9  = does not exist
11 = under (entity/category tree)
12 = not under

Real fields you use most often in actions: _groups_id_assign (technician group), _users_id_assign (technician), slas_id_ttr (resolution SLA), itilcategories_id (category) and urgency. In criteria, _mailgate identifies a ticket that came in through a specific mail collector, and _x-priority reads the email priority header.

Checklist: a rule that fires on the first try

  1. Define the trigger. Reclassifying on creation? Use ONADD (condition 1). Need to react to a category change made afterwards? Also mark update (condition 3).
  2. Choose the right operator. "Is" (0) requires an identical title; to match a substring use "contains" (2) or regex (6). Most title rules that "don't catch" used "is" where they needed "contains".
  3. Position the ranking. Specific first, generic later - but remember the later generic one overwrites. If the generic rule should not touch what was already decided, narrow its criteria.
  4. Check the entity. A rule created in a child entity without the "recursive" flag only applies to that entity's tickets - and disappears for the rest of the estate.
  5. Test in staging before enabling in production.
  6. Validate with Rule Inspector inside a real ticket: it shows which rules were evaluated, which criteria passed and which failed.

Diagnostic SQL: what we run when "the rule doesn't work"

Before touching the interface, NexTool dumps the entire set of ticket rules in evaluation order. Within seconds the ranking tells the story - it is almost always order or condition, not a wrong criterion. Run it on a read replica or carefully on the production database:

SELECT r.ranking,
       r.name,
       IF(r.is_active, 'active', 'INACTIVE') AS state,
       r.match AS logic,
       CASE r.condition WHEN 1 THEN 'on_create'
                        WHEN 2 THEN 'on_update'
                        WHEN 3 THEN 'create+update'
       END AS fires_when,
       (SELECT GROUP_CONCAT(
                 CONCAT(c.criteria, ' [op ', c.condition, '] ', c.pattern)
                 ORDER BY c.id SEPARATOR ' | ')
          FROM glpi_rulecriterias c WHERE c.rules_id = r.id) AS criteria,
       (SELECT GROUP_CONCAT(
                 CONCAT(a.action_type, ':', a.field, '=', a.value)
                 ORDER BY a.id SEPARATOR ' | ')
          FROM glpi_ruleactions a WHERE a.rules_id = r.id) AS actions
FROM glpi_rules r
WHERE r.sub_type = 'RuleTicket'
ORDER BY r.ranking;

Read top to bottom: two rows writing _groups_id_assign mean the one with the higher ranking wins. A row with state = INACTIVE explains the "vanishing" rule. fires_when = on_create explains why editing the ticket does not reroute it.

Decision matrix: which rule collection to use

GLPI has several rule collections, and each behaves differently. Confusing one for another is the root of many "why does this rule run twice?":

CollectionStops at 1st match?Chains the output?Typical use
Ticket business rules (RuleTicket)NoYesClassify, assign group/technician, apply SLA
Mail collector rules (RuleMailCollector)YesNoRoute or reject the email during collection, before the ticket exists
Inventory import (RuleImportAsset)YesNoLink a detected asset to an existing one
Entity import (RuleImportEntity)YesNoSet entity and location on inventory intake
Dictionaries (software, manufacturer)YesNoNormalise messy inventory names

For a ticket that arrives by email, note that two engines run in sequence: first the collector (stops at the first match), then the business engine on the already-created ticket (runs them all).

The common field mistake

In day-to-day maintenance, the ticket we get most about rules is always the same: "I created the rule and it doesn't catch." In the vast majority it is not the criterion - it is the evaluation model. Case number one: two rules write _groups_id_assign, the specific one with a lower ranking matches first, and a generic rule with a higher ranking, created months later "just to guarantee a default group", overwrites everything because the engine chains the output. Case two: the rule was created with condition = 1 only (on creation), so when the agent changes the category later, nothing reroutes. That is why we made it an operating standard to always run the audit SQL above BEFORE touching the interface: the ranking column reveals the conflict in seconds, while clicking rule by rule on screen hides the real execution order. It is the kind of thing that only becomes obvious once you run dozens of environments and see the same pattern repeat.

Need a GLPI whose automation behaves predictably, with no rules stepping on each other? NexTool maintenance audits and reorganises your rule set, and the Rule Inspector plugin shows, inside each ticket, exactly which rule decided what.


Reviewed by the NexTool Solutions team.

Frequently Asked Questions

In maintenance, three causes cover almost everything: the rule is inactive; it was created for creation only (condition 1) and the ticket was edited afterwards; or another rule with a higher ranking overwrites yours, because the RuleTicket engine chains one rule's output into the next rule's input. Run the audit SQL and look at the ranking column before touching the criteria.

"Is" (code 0) requires an identical value; "contains" (code 2) matches a substring. If the category is called "Networks - Wi-Fi" and you use "is" with the pattern "Wi-Fi", it never matches. For substrings, use "contains" or a regular expression (code 6).

No. RuleTicket evaluates all active rules in ascending ranking order and feeds the output of one as the input of the next. The ones that stop at the first match are the mail collector rules and the inventory import rules. That is why order matters so much for tickets.

Create a ticket business rule with a priority or category criterion and an action on the slas_id_ttr field pointing to the resolution SLA. Careful: if the rule only fires on creation (condition 1), changing the priority later will not recalculate the SLA - also mark update (condition 3).

Yes, with one caveat: for email, two engines run in sequence. First the collector rules (RuleMailCollector) during collection, which stop at the first match; then the business rules on the already-created ticket, which run them all. The _mailgate criterion lets you scope a rule to the originating collector.

Need help?