# Troubleshooting Expressions {#troubleshooting-expressions}


Common mistakes when writing validation, skip logic, calculations, and default
values — with symptoms, causes, and fixes.

---


## Wrong variable reference {#wrong-variable-reference}


**Symptom:** the expression evaluates to blank / never matches.

**Cause:** the expression is missing the `${...}` reference braces.

**Incorrect:**

```text
age(dob, visit_date)
```

**Correct:**

```text
age(${dob}, ${visit_date})
```


## Using the question label instead of the variable name {#using-the-question-label-instead-of-the-variable-name}


**Symptom:** the expression never matches what the respondent enters.

**Cause:** expressions must use the question's **variable name** (`name`), not
its displayed label.

**Incorrect:**

```text
What is your date of birth? = '2020-01-01'
```

**Correct:**

```text
${dob} = '2020-01-01'
```


## Wrong argument order {#wrong-argument-order}


**Symptom:** ages, durations, or date differences come out negative or wrong.

**Cause:** argument order is not symmetric across all functions. Verify against
the [Expression Reference](/user-manual/expression-reference.md).

- **`date-diff(unit, start, end)`** — start first, end second.
- **`time-diff(unit, start, end)`** — start first, end second.
- **`duration(end, start, [unit])`** — **end first** (legacy!).
- **`days-between(d1, d2)`** — arg order differs **by platform**; prefer
  `date-diff('days', ...)`.

| Wrong | Right |
|---|---|
| `date-diff('days', ${end}, ${start})` (when you wanted start→end) | `date-diff('days', ${start}, ${end})` |
| `duration(${start}, ${end})` | `duration(${end}, ${start})` |


## Incorrect BMI height unit {#incorrect-bmi-height-unit}


**Symptom:** BMI values are absurdly large.

**Cause:** height passed in metres instead of centimetres.

**Incorrect:**

```text
bmi(70, 1.75)
```

**Correct** (height in cm):

```text
bmi(70, 175)
```


## Invalid date format {#invalid-date-format}


**Symptom:** a date calculation returns blank.

**Cause:** the date isn't a supported format. MQUAD accepts `YYYY-MM-DD` (best),
day-first `DD/MM/YYYY` / `DD-MM-YYYY`, and ISO datetimes. Ambiguous formats
like `03/08/2026` are read **day-first** (3 August).

**Fix:** write dates as `YYYY-MM-DD` in your expressions.


## Comparing a number with text {#comparing-a-number-with-text}


**Symptom:** numeric comparisons behave strangely (e.g. `. >= 18` passes for
`"9"` because `"9" > "18"` lexically in some contexts).

**Cause:** comparing a number to a quoted string.

**Incorrect:**

```text
. >= '18'
```

**Correct:**

```text
. >= 18
```


## Missing quotes around a string {#missing-quotes-around-a-string}


**Symptom:** an equality never matches.

**Cause:** string values must be quoted in the internal format.

**Incorrect:**

```text
${sex} = female
```

**Correct:**

```text
${sex} = 'female'
```

(In the skip-logic **Raw Expression** tab, unquoted values are accepted and
converted for you.)


## Unknown function {#unknown-function}


**Symptom:** the designer flags "Unknown function" when saving.

**Cause:** the function name is not in the whitelist, or is a typo.

**Fix:** check the [Expression Reference](/user-manual/expression-reference.md). Remember
that some functions are platform-specific (`floor`, `ceiling`,
`normalize-space` are backend-only; `pulldata` is mobile-only) — avoid them in
survey logic you need everywhere.


## Unknown unit {#unknown-unit}


**Symptom:** a date/time calculation returns blank.

**Cause:** the unit string isn't recognized.

**Incorrect:**

```text
date-diff('fortnights', ${start}, ${end})
```

**Correct units:**

- `date-diff` / `date-add` / `date-subtract`: `'days'`, `'weeks'`, `'months'`,
  `'years'`
- `time-diff` / `duration`: `'seconds'`, `'minutes'`, `'hours'`, `'days'`

There is no shorthand `d`/`w`/`m`/`y` for the date functions (to avoid
minutes-vs-months confusion).


## Circular calculations {#circular-calculations}


**Symptom:** the designer blocks saving with a circular-dependency error.

**Cause:** two expressions reference each other, e.g. question A's calculation
uses B and B's uses A.

**Fix:** break the cycle — one of the two values should be an input, not a
calculation.


## Calculation is blank / null {#calculation-is-blank--null}


**Symptom:** a calculated field shows nothing.

**Cause:** one of the referenced questions is unanswered, or an argument is
malformed. Any missing/malformed argument makes a function return `null`, and
the field keeps its previous (blank) value.

**Fix:** see [Blank and Invalid Values](/user-manual/blank-and-invalid-values.md). Make
dependency questions Required, and validate inputs.


## Skip condition never becomes true {#skip-condition-never-becomes-true}


**Symptom:** a question never appears.

**Cause:** typically a reference/typo problem — a multi-select compared with
`=` instead of `selected()`, or a comparison against the label rather than the
variable name.

**Fix:** test the condition in Preview. For multi-select use
`selected(${symptoms}, 'fever')`, not `${symptoms} = 'fever'`.


## Validation always fails {#validation-always-fails}


**Symptom:** a question can never be submitted.

**Cause:** the constraint can never be true — e.g. comparing `.` to the wrong
question, `and`/`or` confusion, or a date-order mistake
(`${end_date} > ${start_date}` with a wrong comparison direction).

**Fix:** validate with example values in Preview. For date ranges, ensure the
ordering matches (`end >= start`, not `start >= end`).


## Different default-value reference grammar {#different-default-value-reference-grammar}


**Symptom:** a default value with `${...}` doesn't work, or a calculation with
`#...` doesn't work.

**Cause:** the two grammars are different by design:

| Feature | Reference |
|---|---|
| Default value | `#question_name` (no function calls) |
| Validation / Skip logic / Calculation | `${question_name}` (functions allowed) |

See [Default Values](/user-manual/default-values.md) and
[Auto-Populate and Calculations](/user-manual/calculation-expressions.md).


## Using `<>` for not-equals {#using--for-not-equals}


**Symptom:** the expression doesn't parse or never matches.

**Cause:** `<>` is not supported.

**Fix:** use `!=`.


## Using `? :` ternary in a calculation {#using---ternary-in-a-calculation}


**Symptom:** a calculation that worked in one place doesn't parse on the web
runtime.

**Cause:** the `? :` ternary is only supported by the Flutter expression
engine.

**Fix:** use `if(condition, then, else)`.

---


## Still stuck? {#still-stuck}


1. **Check the reference** — [Expression Reference](/user-manual/expression-reference.md),
   [Date and Time Reference](/user-manual/date-time-reference.md).
2. **Test in Preview** — the designer's Preview mode runs the real runtime.
3. **Check validation messages** — a constraint failure shows the
   `constraint_message` (or a generated explanation); a blank value is usually
   a null-result, not an error.
4. **Ask with the exact expression** — include the question names and the
   expression you wrote; that is usually enough to spot the issue.
