Collect Relevant field not working but works in Enketo

1. What is the issue? Please be detailed.
I have a form hosted on Central 3e9b78f4c7d1636982643585759c3d8a904904e3 (v2026.2.0-1-g3e9b78f) that ultimately looks like the relevance field is not being treated properly in ODK Collect, whereas it is functioning fine in Enketo. The question is in a group with appearance field-list which it looks like historically may have had issues, but not sure if that is related.

Using ODK Collect as username tyler I have a calculate question called c_toshl_account_count with this in the calculation field:

count(instance('toshl_account')/root/item[selected(username, ${username}) and currency=${c_final_currency}])

which returns integers. However, when I put any of the following in the relevant field:
${c_toshl_account_count} > 1
int(${c_toshl_account_count}) > 1
number(${c_toshl_account_count}) > 1

for a selects question, even when it evaluates to 2, the selects question doesn't show.

Column 1 Column 2 Column 3 D E
list_name name label::English (en) username currency
toshl_account 100 Tyler OM tyler GNF
toshl_account 200 T/B GNF Cash tyler , brittany GNF
toshl_account 300 Mamadi GNF Cash mamadi GNF
toshl_account 400 Brittany OM brittany GNF
toshl_account 500 T/B USD Cash tyler USD
toshl_account 600 T/B EUR Cash tyler EUR
toshl_account 700 T/B XOF Cash tyler XOF

2. What steps can we take to reproduce this issue?
As username = tyler and selecting GNF as the currency (so c_final_currency = GNF, c_toshl_account_count evaluates to 2 but the s_toshl_account selects question doesn't show up.

3. What have you tried to fix the issue?
I opened an Enketo Web Form using username URL Parameters and it worked correctly. The fact that it works as intended with Enketo means the logic is correct.

4. Upload any forms or screenshots you can share publicly below.
ODK Collect Bug Relevant.xlsx (119.3 KB) I can send the original .XLSX in a private message.

Enketo Works

Collect Shows the question at the start if GNF is the default as shown below:

but not if there is no default or any other responses have been selected and then GNF is selected again like below:

This error pops up if I hang around in Collect for a while but haven't figured out what triggers it in Collect.

Hi @Tyler_Depke

This might be related to https://github.com/getodk/collect/issues/5152, but I would need to spend more time and see the whole form to confirm. If you can share it pleas do.

Which version of Collect are you seeing this on? You mentioned the Central version, but the Collect one is what matters here.

Thanks for the form @Tyler_Depke

The culprit is c_debug_lookup:

instance('toshl_account')/root/item[selected(username, ${username}) and currency=${c_final_currency}]/name

For your user and GNF this matches two records, so the expression returns two nodes where a single value is expected, and JavaRosa (the engine of ODK Collect) throws an exception. Since all your questions sit in one field-list, that error aborts the rest of the recalculation cascade for the screen - and the relevant condition of s_toshl_account is one of the things that never gets evaluated. That's why the question stays hidden even though c_toshl_account_count is 2.

Neither Enketo nor Web Forms complains here as both silently use the first matching node.

I wouldn't change the strict behaviour itself - silently picking whichever record comes first (Enketo/WebForms) would make your data depend on the row order. What Collect gets wrong is that it doesn’t tell you until you try to navigate to the next screen, and even then, the error message isn’t clear. There’s already an issue for the unhelpful error message here: https://github.com/getodk/javarosa/issues/700, but not for the error not being displayed immediately, so I’m going to file one.

So you have two options for now:

  • Delete the c_debug_lookup row. It's a debug field, so you probably don't need it at all.
  • Keep it, but wrap it in join(): join(' | ', instance('toshl_account')/root/item[selected(username, ${username}) and currency=${c_final_currency}]/name). The error disappears, and the note then prints every matching account instead of blowing up.