fix(SurveyFormBuilder): use nanoid for new option values and remove duplicate onChange call#3818
fix(SurveyFormBuilder): use nanoid for new option values and remove duplicate onChange call#3818nataliapatrucco wants to merge 2 commits intomainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a SurveyFormBuilder SelectQuestion edge case where newly added options could reuse a previously deleted option’s value, leading to collisions and silent deletion failures.
Changes:
- Generate new option
values withnanoid()to avoid add/delete/add collisions. - Remove a redundant duplicate
onQuestionChangecall in the “dedup values”useEffectfallback path.
✅ No New Circular DependenciesNo new circular dependencies detected. Current count: 0 |
📦 Alpha Package Version PublishedUse Use |
🔍 Visual review for your branch is published 🔍Here are the links to: |
Coverage Report for packages/react
File Coverage
|
||||||||||||||||||||||||||||||||||||||
| const newOption = { | ||
| value: `new-option-${optionsLength + 1}`, | ||
| const newOption: SelectQuestionOption = { | ||
| value: nanoid(), |
There was a problem hiding this comment.
Nope, we can't do this, in frontend we use new-option- to detect when these options are new and need to be stored on backend
…uplicate onChange call - Use nanoid() instead of counter-based 'new-option-N' in handleAddOption to prevent value collisions after add-delete-add cycles that triggered the dedup useEffect and broke option identity (causing silent deletion failures) - Remove duplicate onQuestionChange call in the dedup useEffect fallback branch that fired twice with identical data
21b5222 to
5fff09d
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
| const newOption = { | ||
| value: `new-option-${optionsLength + 1}`, | ||
| const newOption: SelectQuestionOption = { | ||
| value: nanoid(), |
There was a problem hiding this comment.
nanoid breaks new-option- prefix backend convention
High Severity
Replacing new-option-${optionsLength + 1} with nanoid() in handleAddOption removes the new-option- prefix that the frontend relies on to signal the backend which options are newly created and need to be persisted. As confirmed by a reviewer, this convention is load-bearing — without it, newly added options won't be stored on the backend, causing silent data loss.
Use `new-option-${nanoid()}` instead of plain `nanoid()` to maintain
the new-option- prefix convention used by consumers to detect new options
while still ensuring value uniqueness to fix the deletion bug.
|
You have used all of your free Bugbot PR reviews. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
|
Updated to use Analysis of the I traced the full round-trip through Factorial's
After the f0 round-trip, What this PR fixes:
|


Summary
Fixes silent deletion failure for newly added answer options in
SelectQuestion(SurveyFormBuilder).Problem
When a user adds options, deletes one, then adds another, the counter-based value generation (
new-option-${options.length + 1}) recycles values, causing collisions. This triggers thesomeOptionsWithSameValuededupuseEffect, which rewrites ALL option values to randomnanoid()strings. The delete handler's closure still holds the pre-rewrite value, so the filteroptions.filter(o => o.value !== params.value)matches nothing — the option silently survives.Additionally, the dedup
useEffectfallback branch calledonQuestionChangetwice with identical data, causing redundant state updates.Changes
handleAddOption: Usenanoid()instead ofnew-option-${optionsLength + 1}to generate unique option values that won't collide after add-delete-add cycles.useEffect: Remove the duplicateonQuestionChangecall in the nanoid fallback branch (lines 74-76 were redundant since line 78 always executed).The dedup
useEffectis kept as a safety net for legacy data that may arrive with duplicate values, but with thenanoid()fix, newly created options will never trigger it.Related
Note
Low Risk
Low risk UI/state fix limited to
SelectQuestion, changing how new option IDs are generated and removing a redundantonQuestionChangecall.Overview
Fixes
SelectQuestionoption value collisions by generating new optionvalues withnanoid()instead of counter-based strings, preventing add/delete/add cycles from reusing IDs.Also removes a redundant
onQuestionChangeinvocation in the duplicate-value dedupuseEffect, avoiding unnecessary duplicate state updates when normalizing option values.Written by Cursor Bugbot for commit 5fff09d. This will update automatically on new commits. Configure here.