▍ humdrum codex / glint v1.1.2
license AGPL-3.0

fix: error messages survive non-key messages

d94299a41774df1cce373e1efe543887e4c96ea7
humdrum-tiv <45084903+humdrum-tiv@users.noreply.github.com> · 2026-07-30 19:01

parent c57f1fb9

fix: error messages survive non-key messages

Error messages set via SetError() were being cleared by any non-key
message (e.g., cursor blink ticks from textinput.Focus()). Now only
actual key presses clear the error display. Added regression test to
verify cursor blinks don't wipe validation messages (TASK-046).

2 files changed

internal/dialog/dialog.go +4 −3
@@ -66,8 +66,9 @@
 // SetWidth sets the content-column width the box is sized against.
 func (m *Model) SetWidth(w int) { m.width = w }
 
-// Update handles one message. Enter confirms, Esc cancels, everything else
-// edits the input (and clears a stale validation message).
+// Update handles one message. Enter confirms, Esc cancels, other key presses
+// edit the input and clear a stale validation message. Non-key messages do not
+// affect the error display.
 func (m *Model) Update(msg tea.Msg) (Result, tea.Cmd) {
 	if k, ok := msg.(tea.KeyMsg); ok {
 		switch k.Type {
@@ -76,8 +77,8 @@ 			return ResultConfirm, nil
 		case tea.KeyEsc:
 			return ResultCancel, nil
 		}
+		m.err = "" // typing clears a stale validation message
 	}
-	m.err = ""
 	var cmd tea.Cmd
 	m.input, cmd = m.input.Update(msg)
 	return ResultNone, cmd
internal/dialog/dialog_test.go +11 −0
@@ -5,6 +5,7 @@ 	"testing"
 
 	"glint/internal/theme"
 
+	"github.com/charmbracelet/bubbles/cursor"
 	tea "github.com/charmbracelet/bubbletea"
 )
 
@@ -95,3 +96,13 @@ 	if m.err != "" {
 		t.Errorf("err = %q after typing, want empty", m.err)
 	}
 }
+
+func TestErrorSurvivesNonKeyMessages(t *testing.T) {
+	m := newModel()
+	m.Open("New note", "~/Notes/", "")
+	m.SetError("Type a name first")
+	m.Update(cursor.BlinkMsg{})
+	if m.err == "" {
+		t.Error("err cleared by a cursor blink; only typing should clear it")
+	}
+}