Advanced Automation Patterns
As your automation library grows, rules interact with each other in complex ways. This page covers advanced patterns for building reliable multi-rule workflows, preventing infinite loops, handling conflicts, optimizing performance, and diagnosing failures.
Multi-rule chaining
Rule chaining occurs when one rule's action produces an event that triggers another rule. This is a powerful pattern for building multi-step workflows.
How chaining works
- Rule A fires on
issue_createdand changes the state to "Triage". - The state change produces a
state_changedevent. - Rule B fires on
state_changedwhere the new state is "Triage" and assigns the triage lead. - The assignee change produces an
assignee_changedevent. - Rule C fires on
assignee_changedand sends a notification to the assignee.
Each rule is independent and reusable. Rule B works whether the state change comes from Rule A, a human, or the API.
Chain example: bug triage workflow
| Step | Rule | Trigger | Condition | Action |
|---|---|---|---|---|
| 1 | New Bug Router | issue_created | Label contains "Bug" | change_state to "Triage" |
| 2 | Triage Assigner | state_changed | New state is "Triage" | assign triage lead |
| 3 | Assignment Notifier | assignee_changed | Assignee was added | send_notification to new assignee |
| 4 | Triage Timeout | scheduled (daily) | State is "Triage" AND updated_at_age_days > 3 | change_priority to "High", add_comment "Triage overdue" |
Design principles for chains
- Keep each rule focused on one responsibility. A rule that does too much is harder to debug and reuse.
- Name rules to indicate their role in the chain. For example: "Step 1: Route new bugs" or "Bug Triage -- Assign Lead".
- Document the chain. Add a comment in each rule's description noting which rules it chains with.
TIP
Draw out your rule chain on paper or a whiteboard before implementing. Identify every event that each action produces, and verify that no unintended chains exist.
Re-entrancy guard
The most dangerous pattern in automation is the infinite loop: Rule A modifies an issue, which triggers Rule B, which modifies the issue again, which triggers Rule A, and so on forever.
How SetGet prevents loops
SetGet includes a built-in re-entrancy guard that limits the depth of rule chains.
| Guard | Behavior |
|---|---|
| Chain depth limit | A single originating event can trigger a maximum chain of 5 rules deep. If rule execution reaches depth 5, further triggered rules are suppressed. |
| Same-rule suppression | A rule does not fire on events produced by its own actions within the same chain. |
| Cooldown window | After a rule fires on a specific work item, it will not fire on the same work item again within 60 seconds, regardless of new events. |
When the guard activates
The re-entrancy guard logs a warning in the Execution History when it suppresses a rule:
Rule "Escalation Handler" suppressed: chain depth limit (5) reached.
Originating event: state_changed on PROJ-142.Designing loop-safe rules
Even with the built-in guard, follow these practices to avoid hitting the limit:
Avoid circular state transitions. Do not create rules where Rule A moves an issue to state X, and Rule B moves it back to the previous state when in state X.
Use conditions to break loops. If Rule A adds a label and Rule B triggers on
label_changed, add a condition to Rule B that checks whether the label was added by an automation (check theactorfield).Do not trigger on your own output. If a rule adds a comment, do not create another rule that triggers on
comment_addedand adds another comment.Use the
manualtrigger for testing. Before connecting a rule to an automatic trigger, test it with a manual trigger to verify it does not produce unintended side effects.
WARNING
The re-entrancy guard is a safety net, not a design tool. Do not rely on it to catch loops in production. Design your rules to be loop-free by construction.
Rule execution order
When a single event matches multiple rules, the execution order is deterministic.
Ordering rules
| Factor | Priority |
|---|---|
| Rule creation order | Rules created earlier execute first |
| Explicit ordering (if configured) | Rules with a lower order number execute first |
Within a rule, actions execute in the order they are listed.
Viewing execution order
- Go to Settings > Automations in the project.
- The rules list shows rules in their execution order.
- Drag and drop rules to reorder them (if explicit ordering is enabled).
Why order matters
If two rules match the same event and both modify the same field (for example, both change the state), the last rule to execute "wins" because its action overwrites the earlier one.
Example of order conflict:
| Order | Rule | Action |
|---|---|---|
| 1 | Route to QA | change_state to "QA Review" |
| 2 | Route to Done | change_state to "Done" |
If both rules match, the final state is "Done" because Rule 2 executes after Rule 1.
TIP
If two rules conflict on the same field, resolve the conflict by adding more specific conditions so that only one rule matches for any given event.
Bulk execution
Some triggers and scenarios cause a rule to match multiple work items at once.
When bulk execution occurs
| Scenario | Behavior |
|---|---|
| Scheduled triggers | The rule evaluates conditions against all work items in the project. Actions execute on every matching item. |
| Manual triggers | Same as scheduled -- all matching items are processed. |
| Bulk updates | If a user updates 20 items at once (e.g., bulk state change), each item generates its own event, and rules evaluate independently for each. |
Bulk execution behavior
- Actions execute sequentially across matching items (item 1 actions, then item 2 actions, and so on).
- If an action fails for one item, processing continues with the next item.
- The execution history records results for each item individually.
- There is no global transaction across items. Each item's actions commit independently.
Performance impact
Bulk execution on large result sets can take time. For a scheduled rule that matches 500 items and performs three actions per item, the total execution involves 1,500 action invocations.
| Items matched | Actions per item | Total actions | Estimated time |
|---|---|---|---|
| 10 | 2 | 20 | < 5 seconds |
| 100 | 2 | 200 | < 30 seconds |
| 500 | 3 | 1,500 | 1-3 minutes |
| 1,000 | 3 | 3,000 | 3-6 minutes |
WARNING
If a scheduled rule matches a very large number of items, consider adding more specific conditions to narrow the scope. Processing thousands of items in a single execution can delay other scheduled rules.
Conflict resolution
When multiple rules match the same event and modify the same work item, conflicts can arise.
Types of conflicts
| Conflict | Example | Resolution |
|---|---|---|
| Same field, different values | Rule A sets priority to "High", Rule B sets priority to "Urgent" | Last-write wins (based on execution order) |
| Contradictory actions | Rule A assigns User X, Rule B unassigns User X | Both actions execute in order. Final state depends on order. |
| Redundant actions | Rule A adds label "Bug", Rule B also adds label "Bug" | No conflict. Second add is a no-op. |
| Complementary actions | Rule A changes state, Rule B adds a label | No conflict. Both actions apply. |
Resolving conflicts
Add specificity to conditions. Ensure conflicting rules have mutually exclusive conditions so only one matches for any given event.
Reorder rules. If two rules must both match, place the one whose result should "win" later in the execution order.
Merge into one rule. If two rules always match the same events, consider merging them into a single rule with multiple actions.
Use labels as gates. Have Rule A add a label, and have Rule B's condition check for that label. This gives you explicit control over which rules execute.
Performance tips
Efficient automation rules reduce execution time and server load.
Condition optimization
| Tip | Rationale |
|---|---|
| Use the most specific trigger type | state_changed is cheaper than issue_updated because fewer events match |
| Put selective conditions first | Short-circuit evaluation stops early on the most selective condition |
Avoid issue_updated with no conditions | This matches every change on every item, which is very expensive |
| Prefer enum comparisons over date calculations | priority equals urgent is faster than updated_at_age_days greater_than 30 |
Action optimization
| Tip | Rationale |
|---|---|
| Minimize webhook calls | External HTTP calls add latency and can fail |
| Batch related changes in one rule | One rule with three actions is faster than three rules with one action each, because it avoids re-evaluation |
| Avoid redundant notifications | If a state change already notifies subscribers, adding a separate send_notification action for the same recipients creates duplicate notifications |
Scheduled rule optimization
| Tip | Rationale |
|---|---|
| Use narrow conditions | Fewer matched items means faster execution |
| Schedule during off-peak hours | Run cleanup rules at 2 AM, not 10 AM |
| Use the minimum viable frequency | Daily is usually sufficient for cleanup; do not schedule every 15 minutes unless truly needed |
Debugging failed rules
When a rule does not produce the expected result, follow this systematic debugging process.
Step 1: Check execution history
- Go to Settings > Automations in the project.
- Click the rule that is not working.
- Open the Execution History tab.
- Review recent executions.
The execution history shows:
| Field | Description |
|---|---|
| Timestamp | When the rule fired |
| Trigger event | The event that triggered the rule |
| Work item | The item that was evaluated |
| Conditions result | Pass or fail, with details on which condition failed |
| Actions result | Success or failure for each action, with error messages |
Step 2: Verify conditions
If the execution history shows "Conditions failed", check each condition:
- Open the work item that should have matched.
- Compare its current field values against each condition in the rule.
- Common issues:
- The field value changed between the trigger event and condition evaluation.
- The condition uses
equalsbut the value has extra whitespace or different casing. - The condition references a label or state that was renamed or deleted.
- AND/OR logic is not what you intended.
Step 3: Verify trigger
If the rule does not appear in the execution history at all:
- Confirm the rule is enabled (not paused or disabled).
- Confirm the trigger type matches the event you expect. For example, changing a label does not fire
state_changed. - For scheduled triggers, check the next run time and timezone.
- Check if the re-entrancy guard suppressed the rule (look for suppression warnings in the history).
Step 4: Test with manual trigger
- Edit the rule and temporarily change the trigger to
manual. - Click Run on the rule.
- Check the execution history for results.
- If the manual run works, the issue is with the trigger configuration, not the conditions or actions.
- Restore the original trigger after testing.
Step 5: Check for conflicts
If the rule executes but the expected outcome does not persist:
- Check if another rule runs after this one and overwrites the change.
- Review the execution history for other rules that fired on the same event.
- Reorder rules or add conditions to eliminate the conflict.
Common debugging scenarios
| Symptom | Likely cause | Fix |
|---|---|---|
| Rule never fires | Wrong trigger type, rule disabled, or re-entrancy guard | Verify trigger type and rule status |
| Rule fires but conditions fail | Field values do not match condition expectations | Review each condition against actual item data |
| Rule fires, actions succeed, but result is wrong | Another rule overwrites the change | Check execution order and conflicting rules |
| Rule fires too often | issue_updated trigger with broad conditions | Switch to a specific trigger or add narrower conditions |
| Scheduled rule does not fire | Wrong timezone, cron syntax error, or rule paused | Verify timezone and cron expression; check next run time |
| Webhook action fails | Target URL unreachable, authentication error, or timeout | Check URL, headers, and server availability |
TIP
Enable verbose logging for a rule temporarily by adding a add_comment action that writes the rule name and timestamp. This creates a visible trace in the work item's activity log that you can review.
Related pages
- Automation Rules -- Creating and managing rules
- Triggers -- All trigger types
- Conditions -- Building condition logic
- Actions -- All action types
- Scheduling -- Time-based rule configuration
- Execution History -- Reviewing past executions
- Built-in Automations -- Auto-Archive and Auto-Close