Universal Field Validator

@UVUNIQUE

@UVUNIQUE is a REDCap action tag that checks a value against every other record as it is typed, with project, DAG or event scope and optional composite keys. REDCap has no native field-level uniqueness.

REDCap has no native field-level uniqueness. @UVUNIQUE checks the value against every other record as it is typed — a CSRF-protected module AJAX call, no page reload — with the usual message / confirm / block enforcement.

Syntax

@UVUNIQUE                       unique across the project

@UVUNIQUE=event                 scope: project | dag | event

@UVUNIQUE={"with":["site"],
           "message":"Specimen already registered",
           "blockSave":"hard"}

@UVUNIQUE={"also":["typed_id"]}  also look in another field

Scopes and composite keys

when decides whether this record's value is checked. Other records are searched whatever their own when says, on the form, in the post-save audit and in the Validation scan.

Under dag scope, records in no group form one group of their own. They are compared against each other, not exempted. "No DAG" is a scope like any other, and the alternative reading — that an ungrouped record has nothing to be compared with — would let the rule lapse exactly where records are hardest to attribute. Use project scope if you want them compared against everything.

Privacy posture

The endpoint answers only for fields that carry a unique rule, so it cannot be used to probe arbitrary fields for the existence of a value. Staff see the colliding record id, and the also field that holds the value, only when the record is inside their own Data Access Group.

What counts as the same value

Stored values, trimmed, with A-Z letter case ignored: SP-1 and sp-1 are duplicates. Add "caseSensitive":true when case tells two values apart. In a field that holds numbers (an integer or number Text field, or a slider) values compare by value, so 007 and 7 are duplicates. On a plain Text field they stay text. @UVEXISTS compares the same way. A saved Missing Data Code is never a duplicate: ten records marked UNK share no value.

Up to 2.1.0-rc.2 the comparison was exact. A project that already holds both spellings of a value gets duplicate findings after the upgrade.

Surveys: opt-in, and never on an identifier

Survey respondents are not logged in, so an "already used" answer tells anyone holding the survey link that a specific value is in the study — one value at a time. {"surveys":true} is therefore:

A reasonable use is a non-identifying response token, to stop the same person submitting twice. Leaving it off costs no data quality: survey submissions are still covered by the post-save audit and the Validation scan.

The race is audited, not denied

Two near-simultaneous saves can both pass the live check. The post-save audit re-checks the saved value against every other record and logs a collision as type: unique, reason: duplicate-value — review the module log for races. A failed check fails open, so a network error on a first check never traps a save. When Save asks again about an "already used" the page has held for 30 seconds or more and gets no answer, that earlier answer stands and is enforced.

Field types

Text, Notes, dropdown, radio, yes/no, true/false and slider. Composes with the other modes on the same field.