Universal Field Validator

@UVASSERT

@UVASSERT is a REDCap action tag that blocks a field unless a condition across other fields holds — date ordering, dose ceilings, confirm-a-value pairs — checked live and enforced at save.

Stock REDCap cannot block a bad relationship between fields at entry: branching only hides, a range check only warns, and Data Quality runs in batch. @UVASSERT closes that gap. The field is invalid unless a condition holds, checked live and enforced with the same message / confirm / block modes as every other rule.

Syntax

@UVASSERT="[end_date]>=[start_date]"

@UVASSERT={"assert":"[dose]<=[max_dose]",
           "message":"Dose exceeds the protocol maximum",
           "blockSave":"hard"}

@UVASSERT={"assert":"[sex]='2'",
           "when":"[pregnant]='1'",
           "message":"Pregnant participants must be recorded female"}

The condition uses the same dialect as the when key: [field] and [checkbox(code)] references, the operators = <> != > < >= <=, and / or / not, and parentheses. ISO dates and numbers compare correctly.

Confirm-a-value pairs

"Type it twice" needs no special feature — it is an assertion:

@UVASSERT="[participant_id]=[participant_id_confirm]"

Things worth knowing before you rely on it

Field types

Text, Notes, dropdown, radio, yes/no, true/false, calc and slider. (Check-character and regex validation stay on Text and Notes.)

Across instruments

Since version 1.6.0 the condition may reference a field on another instrument in the same event. What happens then depends on whether you are entitled to read that field.

Entitled — live, but advisory

For staff data entry with REDCap rights to the other instrument, the off-page value is resolved on the server and baked into the condition, so the check stays live as you type.

It does not block the save, at any blockSave setting. That value is read once, when the page opens, and nothing can refresh it while you type. A concurrent edit on the other form would otherwise produce a wrong block, or a wrong pass, with no way to tell which. A failure names the off-page field and says when it was read, so you know to reload; the post-save audit and the Validation scan are the enforcement record.

Not entitled — deferred, meaning detection rather than prevention

On a survey, or for a user without rights to the referenced instrument, the value is never sent to the page and the rule is deferred: the browser shows no verdict, never blocks, and the save is accepted. redcap_save_record fires after the write, so the audit logs the violation once it has happened and the Validation scan can find it later. Deferring buys privacy at the cost of both live feedback and the block — someone has to read the log or run the scan.

Unresolvable — refused

A field on a different repeating instrument, a field not collected in this event, or a read that failed will stop the rule rather than compare against a blank that was never read. The reason names the field.

Rules whose fields are all on the current instrument are unaffected and still block exactly as before — both sides are live in the form, so nothing is a snapshot. Cross-event references are not supported.