• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kobotoolbox / kpi / 25503822748

07 May 2026 02:59PM UTC coverage: 82.131% (-0.001%) from 82.132%
25503822748

push

github

web-flow
fix(formBuilder): null language on multilingual XLSForm save DEV-2095 (#7020)

### 📣 Summary

Opening the Form Builder fails with a "language needs to be configured"
error after saving a multilingual form (one with labels in multiple
languages and a `default_language` setting).

### 📖 Description

When a multilingual XLSForm (with labels in two or more languages and a
`default_language` set) is uploaded and then edited in the Form Builder,
saving the form once corrupts the language configuration. On the next
attempt to open the Form Builder, an error appears indicating a language
needs to be configured. Visiting "Manage Languages" shows an unknown
blank language has been created, and the form becomes uneditable.

### 💭 Notes

Root cause — frontend (unnullifyTranslations in formBuilderUtils.ts)

When the Form Builder loads, inputParser.parse() mutates its input
object to add translations_0 (the default language name), nullify
translations[0], and normalize settings from an array to an object.
Survey.loadDict was passing state.asset.content directly, so those
mutations landed on the live state.asset.content object. React Query's
background re-fetch then replaced state.asset with a fresh API response,
losing those mutations. launchAppForSurveyContent early-returns because
app is already initialised, so the mutations never run again. At save
time, unnullifyTranslations was reading state.asset.content, found
translations_0 = undefined, set defaultLang = null, and skipped the
rename — plain label keys reached the backend.

**Fix — frontend**

Pass clonedeep(assetContent) to Survey.loadDict so inputParser.parse()
mutates only the copy. state.asset.content stays as the raw API object;
any React Query re-fetch replaces it with identical data and no
mutations are lost.

At both save paths (previewForm and saveForm), pass
app.survey._initialParams to unnullifyTranslations instead of
state.asset.content. _initialParams is assigned at Survey construction
time dire... (continued)

7802 of 11998 branches covered (65.03%)

4 of 4 new or added lines in 1 file covered. (100.0%)

1244 existing lines in 84 files now uncovered.

29619 of 36063 relevant lines covered (82.13%)

5.17 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.66
/kpi/utils/query_parser/query_parser.py


Source Not Available

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc