Skip to content

fix(frontend): stop a cleared number field being read as zero - #262

Merged
dovvnloading merged 1 commit into
mainfrom
fix/cleared-number-field-is-not-zero
Sep 7, 2026
Merged

fix(frontend): stop a cleared number field being read as zero#262
dovvnloading merged 1 commit into
mainfrom
fix/cleared-number-field-is-not-zero

Conversation

@dovvnloading

Copy link
Copy Markdown
Owner

The problem

Number("") is 0, 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:

Field Server bound Result of clearing
num_ctx ge=2048 save rejected, complaining about a value the user never typed
seed ge=-1 save succeeds-1 ("keep replies varied") silently becomes a pinned seed

For 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:

clear Seed (shows "-1" again) -> type "42" -> saved seed: -142

That is worse than the bug being fixed.

The fix

Each field keeps what the user has literally typed while they are typing:

value={numericInputs.seed ?? String(generation.seed ?? -1)}
onChange={(event) => editNumber("seed", event.target.value, (seed) => update({ generation: { ...generation, seed } }))}
onBlur={() => commitNumber("seed")}

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

Test Against original Purpose
clearing both fields saves the existing values, not zeros fails pins the defect
clear Seed, type 42, saves 42 passes guard — this is what caught the -142 regression above

Being straight about the second one: it does not fail against the original code, because there Number("")0 renders "0" and typing 42 gives "042"42. It earns its place as a guard on the editing flow, not as proof of the bug.

Check Result
npm test -- --run 272 passed, 31 files
npm run typecheck clean
npm run lint clean
python -m pytest -q 907 passed

Compatibility 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. temperature is 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

`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>
@dovvnloading
dovvnloading merged commit fc11e31 into main Sep 7, 2026
7 checks passed
@dovvnloading
dovvnloading deleted the fix/cleared-number-field-is-not-zero branch September 7, 2026 15:39
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.

1 participant