Skip to content

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.