Skip to content

Fix #58: mapValidated on MultipleChoice prompts and move error display to bottom#59

Open
kevin-lee wants to merge 1 commit intoneandertech:mainfrom
kevin-lee:fix-validated-multiple-choice
Open

Fix #58: mapValidated on MultipleChoice prompts and move error display to bottom#59
kevin-lee wants to merge 1 commit intoneandertech:mainfrom
kevin-lee:fix-validated-multiple-choice

Conversation

@kevin-lee
Copy link
Copy Markdown
Contributor

@kevin-lee kevin-lee commented Apr 10, 2026

Fix #58: mapValidated on MultipleChoice prompts and move error display to bottom

Bug:

cue4s-multiple-choice-bug.mp4

Why was the error moved to the bottom?

After the first fix, the list rendering was fine, but it had another issue. Please watch this video.

cue4s-multiple-choice-bug-fixed-but-another-bug.mp4

The error message at the bottom (SOLUTION IN THIS PR)

This is a demo of the fix that this PR offers.

cue4s-multiple-choice-bug-fixed-all.mp4

Two bugs existed in PromptFramework.mapValidated when used with MultipleChoice prompts:

  1. After a validation rejection showed an error message, subsequent non-ENTER
    actions (TAB toggle, arrow keys) did not clear the error. The inner
    framework's status was permanently stuck at Running(Left(err)) because
    non-ENTER handlers use identity for status, causing stale error rendering
    and visual artifacts (duplicate/shifted items on terminal).

  2. After a first rejection, selecting then deselecting and pressing ENTER again
    produced no visible feedback because the rendering was already identical to
    the displayed error state.

Fix in PromptFramework.mapValidated (two coordinated changes):

  • renderState: translate the outer wrapper's Running(Left(err)) status
    directly into an inner self.Status.Running(Left(err)) for rendering,
    instead of always reading self.currentStatus() which could be stale.

  • handleEvent: backward-propagate self.Status.Init instead of
    self.Status.Running(Left(err)), guarded by innerWasFinished to only
    apply when the inner was actually Finished (not when it was Running
    with its own validation error, e.g. InteractiveTextInput).

Fix in InteractiveMultipleChoice.renderState:

  • Move the error message rendering from between instructions and options to
    after the options list. When no error is present, a blank line is rendered
    in its place. This keeps the line count constant across error/non-error
    states, preventing terminal scroll-induced cursor offset issues that caused
    duplicate rendering when the prompt was near the terminal bottom.

Also adds a validated-multi interactive example for manual testing.

…ve error display to bottom

Two bugs existed in `PromptFramework.mapValidated` when used with `MultipleChoice` prompts:

1. After a validation rejection showed an error message, subsequent non-ENTER
   actions (TAB toggle, arrow keys) did not clear the error. The inner
   framework's status was permanently stuck at `Running(Left(err))` because
   non-ENTER handlers use `identity` for status, causing stale error rendering
   and visual artifacts (duplicate/shifted items on terminal).

2. After a first rejection, selecting then deselecting and pressing ENTER again
   produced no visible feedback because the rendering was already identical to
   the displayed error state.

Fix in `PromptFramework.mapValidated` (two coordinated changes):

- `renderState`: translate the outer wrapper's `Running(Left(err))` status
  directly into an inner `self.Status.Running(Left(err))` for rendering,
  instead of always reading `self.currentStatus()` which could be stale.

- `handleEvent`: backward-propagate `self.Status.Init` instead of
  `self.Status.Running(Left(err))`, guarded by `innerWasFinished` to only
  apply when the inner was actually `Finished` (not when it was `Running`
  with its own validation error, e.g. `InteractiveTextInput`).

Fix in `InteractiveMultipleChoice.renderState`:

- Move the error message rendering from between instructions and options to
  after the options list. When no error is present, a blank line is rendered
  in its place. This keeps the line count constant across error/non-error
  states, preventing terminal scroll-induced cursor offset issues that caused
  duplicate rendering when the prompt was near the terminal bottom.

Also adds a `validated-multi` interactive example for manual testing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MultipleChoice with mapValidated: Error rendering breaks list when terminal scroll happens

1 participant