# Program Rule Expression Worked Previously but Suddenly Failed on Android Capture

**URL:** <https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877>\
**Category:** Implementation - Implémentation\
**Tags:** tracker, android\
**Created:** [15 September 2026 09:46 UTC](https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877 "2026-09-15T09:46:18Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mr\_jorge](https://dhis2.b-cdn.net/user_avatar/community.dhis2.org/mr_jorge/32/43965_2.png) [@Mr\_jorge](https://community.dhis2.org/u/Mr_jorge)\
**Post date:** [15 September 2026 09:46 UTC](https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877/1 "2026-09-15T09:46:18Z")

</div>

Hi everyone,

I’m experiencing an issue with a DHIS2 Program Rule that I’d appreciate some insight on from the community.

I have a Tracker program with a **multiple-choice data element**. Based on the selection of a specific option (in this case, **“Other – specify”** ), another data element should become visible.

I initially configured the program rule using the following expression:

```plaintext
!d2:validatePattern( #{4.1 Why are new ANC attendees _ receiving MMS _ IFA}, '.*\\b4\\b.*' )

```

This expression worked perfectly during our previous use of the form in **July**. However, when the same form was used again yesterday, the program rule stopped working **during data entry on the Android/mobile app**. The field that should have been revealed remained hidden.

This was particularly problematic because the form had previously worked as expected, so I had no reason to anticipate the issue during data collection.

I had to troubleshoot the issue with the help of Claude AI and eventually changed the expression to:

```plaintext
!d2:validatePattern( #{4.2 Why are new ANC attendees _ receiving MMS}, '^(.*,)?4(,.*)?$' )

```

With this revised expression, the program rule is now working correctly on the mobile app.

### My questions to the DHIS2 community

1. **Why would the original expression stop working when it previously worked correctly with the same form?**
2. Could there have been a change in how DHIS2 evaluates `d2:validatePattern()` or multiple-choice option values, particularly in the Android Capture app?
3. Is the new expression:

```plaintext
'^(.*,)?4(,.*)?$'

```

a reliable approach for checking whether option `4` is selected in a multiple-choice field?  
4. Are there any potential edge cases with this new expression that I should be aware of?  
5. Has anyone else experienced similar behaviour where a program rule works in one period/version of data collection and then unexpectedly stops working later?

I’m mainly trying to determine whether I can **sleep easy with the new expression 😅** , or whether I’ve simply found a workaround that could cause another problem later.

Any explanation from the DHIS2 developers or experienced implementers would be greatly appreciated.

 ![dhis2-program-rule-mystery-1080x1350](https://dhis2.b-cdn.net/uploads/default/original/3X/5/c/5c48aab9d357ad5e3621ecae29ac22862cdd5478.png)

---

<div class="post-metadata">

**Author:** ![Karoline](https://dhis2.b-cdn.net/user_avatar/community.dhis2.org/karoline/32/36_2.png) [@Karoline](https://community.dhis2.org/u/Karoline)\
**Post date:** [28 September 2026 18:39 UTC](https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877/2 "2026-09-28T18:39:50Z")

</div>

Dear @Mr_jorge,  
Sorry that you faced this unexpected issue with a program rule that used to work!

The reason you had to change your expression was because the expression parser version that Android uses was updated in 3.4.2. The change is intended but you are correct in that it would break existing program rules.

> **[Jira](https://dhis2.atlassian.net/browse/DHIS2-21359)**

We will update the docs and also add a note on this in relevant release notes.  
I’ll post here when we have made those updates. 😊

Karoline

---

<div class="post-metadata">

**Author:** ![Gassim](https://dhis2.b-cdn.net/user_avatar/community.dhis2.org/gassim/32/35347_2.png) [@Gassim](https://community.dhis2.org/u/Gassim)\
**Post date:** [1 October 2026 02:18 UTC](https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877/3 "2026-10-01T02:18:27Z")

</div>

Hi there!  
Quick update, the docs have been updated - thanks to @karoline!

> [@Karoline](#):
>
> We will update the docs and also add a note on this in relevant release notes.

> | | | |
> | --- | --- | --- |
> | **d2:validatePattern** | (text, regex-pattern) | Evaluates to true if the input text is an exact match with the supplied regular expression pattern. The pattern is a plain regular expression: write each backslash once, for example `\d` for a digit.   
> **Note:** In DHIS2 versions before 2.41.9, 2.42.6 and 2.43.2, in Android Capture app versions before 3.4.2 and in Capture web app versions before 106.2.3, backslashes had to be doubled (for example `\\d`). The rule behaves according to the version that evaluates it, so review your patterns when you upgrade the server, the Capture web app or the Android Capture app.   
> Example expression, triggering actions if a number is not on the pattern 999999/99/9:  
> `!d2:validatePattern(A{nrc},'\d{6}\/\d{2}\/\d')`   
> Example expression, triggering actions that if the address is not consisting of letters or white spaces, then a white space, then a number:  
> `!d2:validatePattern(A{registrationAddress},'[\w]+ \d+')`   
> Example, triggering actions if a name contains any numbers:  
> `!d2:validatePattern(A{name},'[^\d]*')`   
> Example expression, triggering actions if a mobile number contains the illegal number sequence 555:  
> `d2:validatePattern(A{mobile} ,'.*555.*')` |
> | [(source)](https://docs.dhis2.org/en/use/user-guides/dhis-core-version-master/configuring-the-system/programs.html?h=use#program_rules_operators_functions:~:text=is%20not%20supported.-,d2%3AvalidatePattern,-(text%2C%20regex%2Dpattern) | | |

> [@Mr\_jorge](#):
>
> Any explanation from the DHIS2 developers or experienced implementers would be greatly appreciated.

Hopefully this has helped! 🙏

---

<div class="post-metadata">

**Author:** ![malekpour](https://dhis2.b-cdn.net/user_avatar/community.dhis2.org/malekpour/32/48181_2.png) [@malekpour](https://community.dhis2.org/u/malekpour)\
**Post date:** [1 October 2026 09:50 UTC](https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877/4 "2026-10-01T09:50:37Z")

</div>

Hi @Mr_jorge,

For your specific case of “a reliable approach for checking whether option 4 is selected in a multiple-choice field?”, I suggest using `d2:containsItems` instead of regex matching ([Programs - DHIS2 Documentation](https://docs.dhis2.org/en/use/user-guides/dhis-core-version-243/configuring-the-system/programs.html)):

| d2:containsItems | (text,text, …) | Searches an expression for one or more items. The expression is made up of comma-separated elements. containsItems returns true if every item exactly matches an element in the expression. For example, `containsItems("abcd", "abcd")` and `containsItems("ab,cd", "ab", "cd")` are `true`, but `containsItems("abcd", "b")` and `containsItems("abcd", "ab", "bc")` are `false`. Comparisons are case-sensitive. containsItems can be used for multi-valued data elements to see if an item is contained in the data element values. |
| --- | --- | --- |

---

<div class="post-metadata">

**Author:** ![Mr\_jorge](https://dhis2.b-cdn.net/user_avatar/community.dhis2.org/mr_jorge/32/43965_2.png) [@Mr\_jorge](https://community.dhis2.org/u/Mr_jorge)\
**Post date:** [3 October 2026 22:46 UTC](https://community.dhis2.org/t/program-rule-expression-worked-previously-but-suddenly-failed-on-android-capture/76877/5 "2026-10-03T22:46:13Z")

</div>

Thank you for this @malekpour I will definitely try this out.
