Skip to content

Validation errors on repeating group items show on all instances when only one is invalid #1985

Description

@leoniedickson

Problem

invalidItems in the questionnaire response store is keyed by qItem.linkId. In a repeating group, every instance of a child item shares the same linkId. If one instance is invalid, invalidItems[linkId] is set and every rendered instance of that item shows the error — including instances with valid answers.

Example: a repeating group with a required text field. If the third instance is left empty and "Save as Final" is attempted, all instances show "This field is required", not just the empty one.

Affected validation types:

  • Required — if one instance has no answer, all instances show the required error
  • Format/range (regex, min/max, etc.) — if one instance has an invalid answer, all instances show the format error
  • targetConstraint — not covered by the fix below; see note

Effect on save gate

The save gate introduced in #1974 is unaffected — responseHasErrors correctly reflects whether any instance has errors. This is a display-only bug: errors appear on instances that don't deserve them after highlightRequiredItems() is called.

Proposed fix

Set a unique id on each child QuestionnaireResponseItem within repeat group instances — in useInitialiseRepeatGroups for existing QR data, and wherever new repeat instances are created.

Validation would then key invalidItems by qrItem.id ?? qItem.linkId, and useValidationFeedback (which receives qrItem) would look up the same key. Items outside repeating groups have no id set and fall back to linkId — no behaviour change for non-repeating items.

Files in scope: validate.ts, useValidationFeedback, repeat group initialisation hooks.

Note on targetConstraint in repeating groups

targetConstraint expressions are evaluated once against the entire QuestionnaireResponse as a document, returning a single true/false for the whole QR. There is no per-instance result — the constraint has no way to indicate which specific repeat instance violated it. Re-keying invalidItems by qrItem.id doesn't help here because the single isInvalid flag would still be stored under one key with no instance granularity.

Fixing this would require scoping the expression evaluation to each repeat instance separately — evaluating the constraint once per instance against that instance's subtree of the QR. This warrants a follow-up issue.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions