ADR-0056: Editor validation errors are field-scoped and clear on correction
- Status: Accepted
- Date: 2026-10-17
Context
The transaction and category editors validated on Save by writing a single
error string. Correcting the offending input left the stale message and the
red outline in place until the next Save, and the category editor applied its
one error flag to both the Name and the Budget field, so a single-field failure
marked the whole form red.
Decision
Each editor stores its message together with the field that raised it:
TransactionDraft.errorField (DraftFieldError — a null itemIndex is the
main amount, otherwise the item's name or amount) and
CategoryEditState.errorField (CategoryField.NAME / BUDGET). Every edit
that can change a validated value re-evaluates only the field the current error
points at, using the rule that raised it — non-blank parseable amount, non-blank
item name, blank-or-parseable item amount, non-blank name, blank-or-positive
budget. Once that value satisfies the rule the message and the red outline
clear; otherwise the error stands. Removing the errored item clears its error.
Unrelated errors are never touched.
Save keeps validating every field from scratch, so clearing a message never
bypasses a rule: duplicate category names and unparseable or non-positive
amounts are re-checked on every Save. The message renders as the field's
supporting text (AmountCurrencyFields, ItemizationSection,
CategoryEditContent), which keeps it in the field's semantics for assistive
tech; the main-amount error still drives amount focus and item errors still
expand the Items section.
Consequences
Users see the error disappear as they fix it, and a repeated Save failure keeps the message until the value is genuinely valid. Errors are per-field state, so adding a new validated field means adding its identity to the editor's field type rather than reusing the shared message. Edit-time revalidation of a duplicate name clears the message optimistically; Save re-detects the duplicate and re-raises the same field-scoped error.
Verification
TransactionDraftValidationTest and CategoryEditValidationTest cover
correction, still-invalid values, unrelated-error preservation and removed
items. TransactionDetailScreenTest drives the real editor (corrected amount
clears before the next Save, an item error survives an amount edit,
unparseable input keeps its error) and CategoryEditContentTest plus
CategoryEditViewModelTest cover per-field marking, duplicate names and error
clearing.