fix(frontend): stop a cleared number field being read as zero - #262
Merged
Conversation
`Number("")` is 0, so clearing the Context window or Seed box to retype it
wrote a real zero into the settings draft.
For the context window that is below the server's minimum (`ge=2048`), so the
save was rejected and the message talked about a value the user never typed.
For the seed it is worse, because 0 is *valid* (`ge=-1`): the save succeeded
and silently turned "-1, keep replies varied" into a pinned seed, making every
later reply deterministic with nothing on screen to explain it.
Ignoring an empty field is not enough on its own. Both inputs are bound
directly to the saved numbers, which can never be empty, so the old value
snapped straight back and the digits typed next appended to it -- clearing
Seed and typing "42" saved -142. My first attempt did exactly that; the
retype test below is what caught it.
Each field now keeps what the user has literally typed while they are typing,
so the box can be empty mid-edit without any number being written, and the
override is dropped on blur so the field re-syncs to whatever was actually
saved. A parsed value is committed only when the text is a finite number.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The problem
Number("")is0, so clearing the Context window or Seed box to retype it wrote a real zero into the settings draft.The two fields fail differently, and the second is the worse one:
num_ctxge=2048seedge=-1-1("keep replies varied") silently becomes a pinned seedFor the seed there is no error and nothing on screen to explain it. Every later reply becomes deterministic because a field was cleared.
Ignoring an empty field is not enough
My first attempt simply skipped the update when the text was empty. That is wrong in a way worth recording, because the test caught it:
Both inputs are bound directly to the saved numbers, which can never be empty. So clearing the box didn't clear it — the old value snapped straight back, and the digits typed next appended to it:
That is worse than the bug being fixed.
The fix
Each field keeps what the user has literally typed while they are typing:
So the box can genuinely be empty mid-edit without any number being written, a value is committed only when the text parses to a finite number, and the override is dropped on blur so the field re-syncs to whatever was actually saved.
Verification
42, saves42-142regression aboveBeing straight about the second one: it does not fail against the original code, because there
Number("")→0renders"0"and typing42gives"042"→42. It earns its place as a guard on the editing flow, not as proof of the bug.npm test -- --runnpm run typechecknpm run lintpython -m pytest -qCompatibility and rollback
One component's local state; the saved settings shape is untouched. A field edited to a valid number behaves exactly as before. No API contract, stored data, or migration. Reverting the commit restores the previous behaviour exactly.
Limits
The raw-text override covers these two fields only.
temperatureis a range slider and cannot be cleared, so it has the same binding without the same exposure — but the pattern is now here if another free-text number field is added.An out-of-range number typed in full (say a context window of
100) is still committed to the draft and refused by the server on save. That is the existing contract, and inline validation is a separate piece of work from not inventing a value the user never entered.🤖 Generated with Claude Code