Using rule debugger changes the outcome of rules


I have found that whether or not I have “Show Rule Debugger” enabled changes the outcome of a particular set of rules I want to use. This is very strange, surely the outcome of the rule processing should be consistent whether or not the rule debugger is in-use?

You can see this by starting with a blank database and adding the following Order Tags, Actions and Rules… (This is the contents of a rule export, just copy it to a text file and you should be able to import it).

You will also need to add mapping to the three OrderTag groups in this import and you will need to add a product to a menu.

{"AccountScreens":null,"AccountTransactionDocumentTypes":null,"AccountTransactionTypes":null,"AccountTypes":null,"Accounts":null,"Actions":[{"ActionType":"TagOrder","Name":"X Tag Order","Parameter":"[{\"Key\":\"OrderTagName\",\"Value\":\"[:Tag Name]\"},{\"Key\":\"OldOrderTagValue\",\"Value\":\"\"},{\"Key\":\"OrderTagValue\",\"Value\":\"[:Tag Value]\"},{\"Key\":\"OrderTagNote\",\"Value\":null},{\"Key\":\"OrderTagPrice\",\"Value\":null},{\"Key\":\"OrderTagRate\",\"Value\":null},{\"Key\":\"RequireSelection\",\"Value\":null}]","SortOrder":0},{"ActionType":"UntagOrder","Name":"X Untag Order","Parameter":"[{\"Key\":\"OrderTagName\",\"Value\":\"[:Tag Name]\"},{\"Key\":\"OrderTagValue\",\"Value\":\"[:Tag Value]\"},{\"Key\":\"RequireSelection\",\"Value\":null}]","SortOrder":0}],"AutoConfigurationTasks":null,"AutomationCommands":null,"CalculationSelectors":null,"CalculationTypes":null,"ChangePaymentTypes":null,"CustomReports":null,"Departments":null,"EntityScreens":null,"EntityTypes":null,"Numerators":null,"OrderTagGroups":[{"AddTagPriceToOrderPrice":false,"ButtonColor":null,"ButtonHeight":65,"ColumnCount":5,"FontSize":14,"FreeTagging":false,"GroupTag":null,"Hidden":false,"MaxSelectedItems":1,"MinSelectedItems":1,"Name":"DiveType","OrderTags":[{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"AM","Price":0.0000,"Rate":0.00,"SortOrder":10},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"MID","Price":0.0000,"Rate":0.00,"SortOrder":20},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"PM","Price":0.0000,"Rate":0.00,"SortOrder":30},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"Pool1","Price":0.0000,"Rate":0.00,"SortOrder":40},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"Pool2","Price":0.0000,"Rate":0.00,"SortOrder":50},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"Other1","Price":0.0000,"Rate":0.00,"SortOrder":60},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"Other2","Price":0.0000,"Rate":0.00,"SortOrder":70},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"Other3","Price":0.0000,"Rate":0.00,"SortOrder":80}],"Prefixes":"[]","SaveFreeTags":false,"SortOrder":10,"TaxFree":false},{"AddTagPriceToOrderPrice":false,"ButtonColor":null,"ButtonHeight":65,"ColumnCount":5,"FontSize":14,"FreeTagging":false,"GroupTag":null,"Hidden":false,"MaxSelectedItems":1,"MinSelectedItems":0,"Name":"Tank1","OrderTags":[{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"1Air","Price":0.0000,"Rate":0.00,"SortOrder":10},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"1Nitrox","Price":0.0000,"Rate":0.00,"SortOrder":20},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"1Low","Price":0.0000,"Rate":0.00,"SortOrder":30},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"1None","Price":0.0000,"Rate":0.00,"SortOrder":40}],"Prefixes":"[]","SaveFreeTags":false,"SortOrder":20,"TaxFree":false},{"AddTagPriceToOrderPrice":false,"ButtonColor":null,"ButtonHeight":65,"ColumnCount":5,"FontSize":14,"FreeTagging":false,"GroupTag":null,"Hidden":false,"MaxSelectedItems":1,"MinSelectedItems":0,"Name":"Tank2","OrderTags":[{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"2Air","Price":0.0000,"Rate":0.00,"SortOrder":10},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"2Nitrox","Price":0.0000,"Rate":0.00,"SortOrder":20},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"2Low","Price":0.0000,"Rate":0.00,"SortOrder":30},{"Color":null,"Description":null,"Filter":null,"Header":null,"MaxQuantity":1,"Name":"2None","Price":0.0000,"Rate":0.00,"SortOrder":40}],"Prefixes":"[]","SaveFreeTags":false,"SortOrder":30,"TaxFree":false}],"PaymentTypes":null,"PrintJobs":null,"PrinterTemplates":null,"Printers":null,"ProgramSettingValues":null,"Rules":[{"Actions":[{"ActionName":null,"CustomConstraint":null,"Name":"X Untag Order","ParameterValues":"Tag Name=Tank1`Tag Value={ORDER TAG:Tank1}","SortOrder":10},{"ActionName":null,"CustomConstraint":null,"Name":"X Untag Order","ParameterValues":"Tag Name=Tank2`Tag Value={ORDER TAG:Tank2}","SortOrder":20}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"OrderUntagged","Name":"X Reset tags","RuleConstraints":"[]","SortOrder":10,"Tags":null},{"Actions":[{"ActionName":null,"CustomConstraint":null,"Name":"X Tag Order","ParameterValues":"Tag Name=Tank1`Tag Value=1Low","SortOrder":10},{"ActionName":null,"CustomConstraint":null,"Name":"X Tag Order","ParameterValues":"Tag Name=Tank2`Tag Value=2None","SortOrder":20}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"OrderTagged","Name":"X 1 Tag pool tanks","RuleConstraints":"[{\"L\":\"OrderTagName\",\"N\":\"TSD0lAEHYV\",\"O\":\"Equal\",\"R\":\"DiveType\"},{\"L\":\"OrderTagValue\",\"N\":\"gRE8IuTlGc\",\"O\":\"Starts\",\"R\":\"Pool\"}]","SortOrder":20,"Tags":""},{"Actions":[{"ActionName":null,"CustomConstraint":null,"Name":"X Tag Order","ParameterValues":"Tag Name=Tank1`Tag Value=1Nitrox","SortOrder":10},{"ActionName":null,"CustomConstraint":null,"Name":"X Tag Order","ParameterValues":"Tag Name=Tank2`Tag Value=2Nitrox","SortOrder":20}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"OrderTagged","Name":"X 2 Tag nitrox tanks","RuleConstraints":"[{\"L\":\"OrderTagName\",\"N\":\"TSD0lAEHYV\",\"O\":\"Equal\",\"R\":\"DiveType\"},{\"L\":\"OrderTagValue\",\"N\":\"gRE8IuTlGc\",\"O\":\"Equal\",\"R\":\"AM\"}]","SortOrder":30,"Tags":""},{"Actions":[{"ActionName":null,"CustomConstraint":null,"Name":"X Tag Order","ParameterValues":"Tag Name=Tank2`Tag Value=2None","SortOrder":10}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"OrderTagged","Name":"X 3 Tag MID","RuleConstraints":"[{\"L\":\"OrderTagName\",\"N\":\"TSD0lAEHYV\",\"O\":\"Equal\",\"R\":\"DiveType\"},{\"L\":\"OrderTagValue\",\"N\":\"gRE8IuTlGc\",\"O\":\"Equal\",\"R\":\"MID\"}]","SortOrder":40,"Tags":""},{"Actions":[{"ActionName":null,"CustomConstraint":"'{ORDER TAG:Tank1}' == ''","Name":"X Tag Order","ParameterValues":"Tag Name=Tank1`Tag Value=1Air","SortOrder":10},{"ActionName":null,"CustomConstraint":"'{ORDER TAG:Tank2}' == ''","Name":"X Tag Order","ParameterValues":"Tag Name=Tank2`Tag Value=2Air","SortOrder":20}],"AppRuleMaps":[{"DepartmentId":0,"TerminalId":0,"TicketTypeId":0,"UserRoleId":0}],"ConstraintMatch":0,"EventName":"OrderTagged","Name":"X 9 Tag air","RuleConstraints":"[{\"L\":\"OrderTagName\",\"N\":\"TSD0lAEHYV\",\"O\":\"Equal\",\"R\":\"DiveType\"}]","SortOrder":50,"Tags":""}],"Scripts":null,"States":null,"TaskTypes":null,"TicketTagGroups":null,"TicketTypes":null,"Triggers":null}

Take a close look at the Tank1 and Tank2 tags that get selected when choosing either AM, MID or a Pool for the dive type…

Desired behavior (seen when Show Rule Debugger is enabled)

  • AM - Tank1 and Tank2 are set to Nitrox
  • MID - Tank1 set to Air and Tank2 set to None
  • Pool - Tank1 set to Low and Tank2 set to None
  • All other types - Tank1 and Tank2 set to Air

When the rules debugger is not enabled all tanks incorrectly get assigned as Air (apart from MID which gets an even more weird result that I don’t understand at all).

Any idea why enabling/disabling the rule debugger is changing the result of these rules?
When investigating, I noticed that if I use a “Show Message” to display the current value you the {ORDER TAG:Tank1} it always displays perfectly BUT it seems that it is evaluated incorrectly when used in a rule constraint (when rule debugging is disabled).

PS: I know there are probably easier ways to do this, but in reality I have many more dive types, tank types and logic to assign the correct tanks and using multiple sequentially firing rules is going to be by far the easiest way for me to maintain this logic, rather than a ton of rules with long string of rule constraints.


This is a known issue for some time, I’ve experienced it before and spent a long time wondering why things just didn’t make sense until I then turned off rule debugger and it worked. I also reported it in the past and I think a reason was given as to why its like that. Because of this I don’t use rule debugger except if I really need to confirm if a rule is firing or not. I usually use Show Message to display output if I want to check something.

I think it comes down to limitations in the way rule debugger works and isn’t something that can be easily resolved.


Ah, OK. That’s disappointing.

Any idea why the result of {ORDER TAG:} would be different when used as a constraint as opposed to when it is used in a show message?


Can you show what constraint your trying to use?


Typically ORDER TAG:X is only available inside an order. I would need to see how your using it.


Created a couple of rules… Crucially, X1 is sorted in front X9

X1 Rule:


X9 Rule:



This message comes up when I tag an order as “pool”… As you can see, the content shows the value of Tank1, but the contraint has seen it as empty…


What happens if you set it as'{ORDER TAG:Tank1}' == '1'


Rule degbuger enabled

'{ORDER TAG:Tank1}' == '' No message
'{ORDER TAG:Tank1}' == '1Low' Message appears

Rule degbuger disabled

'{ORDER TAG:Tank1}' == '1Low' No message
'{ORDER TAG:Tank1}' == '' Message appears

The expected behaviour is only seen when rule debugger is enabled…

Weird, right?
I have tried this on multiple 5.2.18 installations and using a fresh DB


I tried moving the contraint to be for the entire rule, but the same unexpected behaviour was seen…


On few recent releases I made lots of optimizations to be able to make rules run faster. To achieve that some tag reading tasks works in background. Displaying a message box or running rule debugger generally forces background tasks to complete immediately so it may produce unexpected results.

If you can reproduce it on default database I’ll be glad if you can prepare me a backup so I can debug that.


Thanks @emre, that would explain it.

If you could find a way to make this work that would be great - I have been scratching my head on this one for a while!

The backup is (466.4 KB)


Thank you very much for the backup @mjb2000.

If possible can you explain me shortly which steps I need to follow to see it?

  1. POS
  2. Select customer “T”
  3. Add product “Dive”
  4. Select the “Dive” order
  5. Tag the order as “Pool1”

You will see the “Show Message” from rule X9.

When Rule Debugger is turned on you won’t see the message and the tanks should be set to 1Low and 2None.


Which one works as expected ? When rule debugger enabled ?


Yes, rule debugging enabled works as expected.

If you remove the “Show Message” from X9 which I only added for testing then you should see the following tanks tagged when you select the dive trip:

Desired behavior (seen when Show Rule Debugger is enabled)

  • AM - Tank1 and Tank2 are set to Nitrox
  • MID - Tank1 set to Air and Tank2 set to None
  • Pool - Tank1 set to Low and Tank2 set to None
  • All other types - Tank1 and Tank2 set to Air


I guess the rule debugger somehow forces the {ORDER TAG:X} to be evaluated in real-time rather than in the background.


The action constraints works like that …

When you Tag the Order with “pool1” SambaPOS first finds rules that are about to execute and evaluates constraints to determine which actions will work.

So as soon as you select Pool1 Tag these rules are selected to execute.

  • X 1 Tag pool tanks
  • X 9 Tag air

On next step SambaPOS evals constraints to select actions. So “Show Message” action selects as “Tank1” tag is not selected yet.

SambaPOS executes all actions that matches the constraint in that order.

  1. X Tag Order > Tank1 Low 1
  2. X Tag Order > Tank2 2None
  3. X Show Message (Tank1 set at first step so you see the value here. Constraint will not reevaluate here as it already evaluated.)
  4. X Tag Order > Tank1 1Air (Same thing here. It works as constraint was matching while rule being selected)
  5. X Tag Order > Tank2 2Air

So you need to take into account constraints only works while actions first selected. After it selected previously running actions will not prevent action to run.

So how it runs when rule debugger is disabled is the expected behavior. Now I’ll check how it works when rule debugger it enabled.

PS: To solve that you need to use ExecuteAutomationCommand action. That is useful to chain rules as you want. It ensures rule evaluates after certain actions executes.


OK It may sound weird but Rule Debugger evaluates constraints just before action executes so it works as you’ve expected @mjb2000. I fixed that so it will work as it works when rule debugger is not enabled.

Evaluating all constraints before actions executes is something we decided while implementing the action constraint feature. Your case might seem like it shouldn’t do that but we unknowingly depend it a lot on a lot of configurations.

When it depends the result of previously running actions it really breaks easily. Running them in advance simplifies a lot of different cases.


Ahhh… Thanks for explaining @emre

I will look in to how to use ExecuteAutomationCommand…

Thanks for your time in explaining this, sorry to waste your time… At least things will be a little more consistent with the rule debugger now :slight_smile:


This is not a waste of my time. Rule Debugger misleaded you. Sorry for that.
That was an old mystery with the rule debugger and we finally spotted it.
Thank you very much for reporting and helping me to resolve that.