removeValue on array field incorrectly sets isTouched=true on all shifted siblings
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 6.7k
- Forks
- 682
- Avg merge
- 5d 18h
- Merged PRs (30d)
- 7
Description
Describe the bug
Calling form.removeValue(index) on an array field flips isTouched to true on every sibling at index ≥ removed index. Even when the user has never interacted with those fields.
The bug lives in @tanstack/form-core, so every adapter (react, vue, solid, svelte, angular, lit) is affected.
Your minimal, reproducible example
https://github.com/ntatoud/repro-tanstack-form-removevalue-touched.git
Steps to reproduce
git clone https://github.com/ntatoud/repro-tanstack-form-removevalue-touched.gitnpm install && npm run test(deterministic vitest assertion)npm run dev- Click 'remove index 2' button.
- Notice how all shifted elements are not marked as touched.
Expected behavior
isTouched stays false on every remaining item: The user never touched anything.
values = ['a', 'b', 'd', 'e']
touched = [false, false, false, false]
How often does this bug happen?
Every time
Screenshots or Videos
https://github.com/user-attachments/assets/3b884c33-a58f-4892-90ab-86c547180d1e
Platform
- OS: macOS 26.2
- Node: 24.15.0
- Browser: any (not related to browser)
TanStack Form adapter
react-form
TanStack Form version
1.29.0
TypeScript version
6.0.2
Additional context
Adapter-agnostic: bug is in form-core, not the React bindings
Proposed fix
In validateArrayFieldsStartingFrom, bypass validateField when the field already has a mounted instance and call fieldInstance.validate(cause) directly. This preserves validation, skipping the auto-touch:
// packages/form-core/src/FormApi.ts
batch(() => {
fieldsToValidate.forEach((nestedField) => {
fieldValidationPromises.push(
Promise.resolve().then(() => {
const fieldInstance = this.fieldInfo[nestedField]?.instance
if (fieldInstance) {
return fieldInstance.validate(cause)
}
return this.validateField(nestedField, cause)
}),
)
})
})
Verified locally by patching node_modules/@tanstack/form-core/dist/esm/FormApi.js.
The same fix likely applies to swapFieldValues / moveFieldValues / insertFieldValue if they call validateArrayFieldsStartingFrom (worth auditing as a follow-up)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/form-core/src/FormApi.ts at validateArrayFieldsStartingFrom and reproduce the issue with the linked example using npm install && npm run test. Check how array removal validates shifted fields and verify that the remaining items retain isTouched=false; audit the related array operations mentioned in the issue as a follow-up.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100