Sync error when editing Data Elements in existing event with Program Rule assign

Hello DHIS2 Community,

I am experiencing sync errors in the Android Capture app when editing an existing tracker event that has a program rule assigning a sum of numeric Data Elements to a total DE.

Environment:

  • DHIS2 version: 2.42.4.1
  • Android Capture version: 3.4.1
  • Program type: Tracker

Program Rule Setup:

  • Condition: d2:hasValue(#{VAR_NAME})
  • Action: Assign value to a Positive Integer DE
  • Expression: sum of ~47 numeric DEs using d2:zing() to handle nulls

Scenarios:

  1. Create and sync a new event – always works
  2. Edit numeric DEs only and sync changes - always works
  3. Edit #{VAR_NAME} (option set) only- Intermittent - sometimes works, sometimes fails
  4. Edit #{VAR_NAME} + numeric DE simultaneously - :cross_mark: always fails

Examples of error messages:

  1. [{“a”:“Jul 7, 2026 18:29:11”,“b”:“E1307”,“c”:“Generated by ProgramRule (ELofqjfnHyk) - Unable to assign value to DataElement w4JOVpBvXfo. The provided value must be empty or match the calculated value 0”,“d”:“ERROR”,“e”:true}] (3-d scenario)
  2. [{“a”:“Jul 7, 2026 18:31:22”,“b”:“E1307”,“c”:“Generated by ProgramRule (ELofqjfnHyk) - Unable to assign value to DataElement w4JOVpBvXfo. The provided value must be empty or match the calculated value 30”,“d”:“ERROR”,“e”:true}, (4-th scenario)

What I have tried:

  • Changed condition from d2:hasValue(#{HBC_Category}) to (sum) >= 0 — made things worse, backend only sees edited field values
  • Wrapped all DE variables in d2:zing() — improved stability but did not fully resolve
  • Upgraded from Android 3.4.0.1 to 3.4.1 — partial improvement

Root cause hypothesis:

When editing an existing event, the backend program rule engine appears to only evaluate DE values included in the current sync payload, treating all unedited DEs as 0. This causes the recalculated sum to mismatch the stored total, resulting in a sync error.

I found a related to my issue Jira Ticket

But the status is “Won’t Do”

I would highly appreciate any workarounds, design patterns, or insights from anyone who has faced this issue and found a solution

Update

For now I found a temporary solution:

curl -X POST “https://your_url/api/systemSettings/ruleEngineAssignOverwrite” \
-d “true” \
-H “Content-Type: text/plain” \
-u admin:your_password

But the question is:

“What are pros and cons of such a solution? And what are possible implications?”

Hi

@m.siusko .. to be honest, the question was a bit complex at start but I see your point completely. I have a curious question: is ‘editing’ existing values in an event part of the workflow or is it when for instance an error occurs during data entry? If it’s part of the workflow, I am wondering why - that’s all. :slight_smile:

To be honest, I will have to leave this backend program rule engine functionality to the @dhis2-android team… to clarify!

I’m not sure that this is the best solution because of two main reasons:

  1. The reason why we have those errors is being ignored and AFAIK those errors are because there’s an issue with the program rule calculation so ignoring the error and passing the result as it is might result with an incorrect ‘recalculated sum’.
  2. This system setting will apply globally to all programs in the instance and I don’t think that this is the expert recommendation.

I’m sorry for not providing an exact solution to this one, this one does need triaging so someone for the team will get to this asap. Thanks for your understanding! :folded_hands:

Hey @Gassim, thanks for the quick reply and for looping in the android team!

To answer your question: no, editing isn’t a planned part of our workflow. It’s strictly for fixing typos and mistakes made during initial data entry. A lot of our users are 60+, so accidental misclicks and errors just happen naturally. They need a straightforward way to correct those slips, otherwise our data quality takes a big hit.

And you are totally right about that workaround-flipping a global system setting to just ignore validation errors sounds like a recipe for disaster across the whole instance. We definitely want to avoid that.

Really appreciate you pushing this forward to the @dhis2-android team for triaging. Hopefully, they can track down why the backend is treating unedited fields as zero during a partial payload sync!

Hello @m.siusko,

this problem looks similar to other issues we have had and solved in the Android app, but I think it has a few different things. I have been trying to reproduce the issue without success. This is what I have tried:

  • Set up the instance Login app | DHIS2
  • Created a program rule in Child programme for the Birth stage. It checks if the data value for OPV dose (optionSet) has value or not. Then, the action is to assign the sum of three data values wrapped with `d2:zing` to another data value.

Would you have the time to check it and modify it as you want so that we can have an instance where we could reproduce it? If you have a testing instance you can share with us, it would be awesome as well.

Thanks!