Blank and Invalid Values
This page documents what MQUAD actually does when a value is missing, blank, malformed, or unexpected. The rules below are frozen for the calculation functions and verified across web, mobile, and backend.
The core rule: missing input → null
For every calculation function, any missing / null / empty / malformed
argument, wrong argument count, or unknown unit returns null. Functions
never throw, never abort the enclosing expression, and never produce 0 or an
empty string just because an input was bad.
When a calculation returns null, the question's stored value is left
unchanged (it keeps its previous value). A later valid result overwrites
it.
What happens in each situation
| Situation | Result |
|---|---|
| Referenced question has not been answered yet | The reference resolves to blank/null → functions that use it return null |
Date is invalid or malformed (age('not-a-date', '2026-08-14')) | null |
Calculation argument is null (bmi(null, 175)) | null — not 0 |
Unit is unknown (date-diff('fortnights', ...)) | null |
Height is zero or negative (bmi(70, 0)) | null |
Weight is non-numeric (bmi('abc', 175)) | null |
Wrong argument count (age('2000-01-01')) | null |
End date before start date (date-diff('days', ${end}, ${start})) | a negative number (date-diff is signed) |
LMP after reference date (gestational-weeks(${future_lmp}, ${visit})) | 0 (gestational functions clamp to 0) |
DOB after reference date (age(${future_dob}, ${visit})) | 0 (age functions clamp to 0) |
Mixed plain-time + datetime (time-diff('hours', '09:00', '2026-08-14T10:00:00Z')) | null |
| Question is hidden by skip logic | its stored answer is retained; if it was never answered, references resolve to blank |
Non-numeric amount in date-add (date-add('2026-08-14', 'x', 'days')) | null |
Worked examples
bmi(null, 175) → null
date-diff('fortnights', '2026-08-01', '2026-08-14') → null
date-diff('months', '', '2026-08-14') → null
age('not-a-date', '2026-08-14') → null
date-add('2026-08-14', 'x', 'days') → nullMQUAD does not show a visible error message when a function returns null — the result is simply blank. If blank results are a problem, add a Validation rule to prevent bad input in the first place.
Validation vs null
Validation (constraints) is skipped for empty values — an unanswered question only fails if it is marked Required. This means:
- An empty
symptomsanswer does not failcount-selected(${symptoms}) >= 2. - It fails only if the field is Required.
If a field must be validated only when answered, that is the default behaviour. If it must be required under a condition, use:
if(${has_children} = 'yes', . != '', .)Hidden questions
When a question is hidden by Skip Logic, its previously entered answer is retained, not erased. References to a hidden-but-answered question still resolve. If a question was never shown and never answered, references to it resolve to blank.
If you need a hidden question's stale value cleared, add a calculation that
clears it (e.g. an if() that yields blank), or clear it manually.
Preventing problems
Because null results are silent, the practical guidance is:
- Validate inputs — numeric range checks (
bmi, age inputs), date order checks (end ≥ start), required checks. - Use the signed rule —
date-diffreturns negatives for reversed dates; validate with${end_date} >= ${start_date}instead of guessing. - Reference dates explicitly —
age(${dob}, ${interview_date})fails tonullif either date is blank; make both questions Required. - Test in Preview — open your survey in Preview mode and step through the cases you care about before publishing.
