Field variables added in-session are silently deleted when the field's properties are saved
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 970
- Forks
- 486
- Avg merge
- 3d 33m
- Merged PRs (30d)
- 170
Description
Problem Statement
Field variables added to a content type field during a browser session are silently deleted as soon as that field's properties are saved. There is no warning, no error toast, and no console error — the variable simply disappears.
This is data loss in a normal, expected editing flow: an editor adds a field variable, then tweaks something on the same field's Overview tab (Hint, Name, Default Value, a checkbox), clicks Save, and the field variable they just created is gone.
Found while QA'ing #35512 (verifying PR #36341). This defect is not caused by that PR — see "Regression status" below.
Root cause (identified): the field-edit dialog holds a field object snapshotted at page load. The Field Variables tab writes through its own endpoint (POST /api/v1/contenttype/{ctId}/fields/id/{fieldId}/variables) and never refreshes that snapshot. When the field's properties are then saved, the client issues:
PUT /api/v3/contenttype/{ctId}/fields/{fieldId}
{"field": { ... , "fieldVariables": [], ... }}
The backend treats that stale fieldVariables array as authoritative and replaces the field's variables with it, deleting anything added since page load.
Captured request body from a real reproduction:
{"field":{"clazz":"com.dotcms.contenttype.model.field.ImmutableTextField","contentTypeId":"bb975b4dbd1e79168c130dd3b3fcbf69","dataType":"TEXT","fieldType":"Text","fieldVariables":[],"id":"66f7c1cc436224db0e865ab94579d85b","name":"Field One EDITED","variable":"fieldOne","hint":"a hint added after the variable", ...}}
Browser & OS: Chrome 152 / macOS. Not browser-specific — the defect is in the request payload.
Steps to Reproduce
100% reproducible. Verified twice, on two different fields, on two different field types (Text, Checkbox).
- Edit any content type, then click any field to open the field-edit dialog.
- Go to the Field Variables tab, add a variable — key
newVar, valuenewValue— and save it.- Confirm it saved:
GET /api/v1/contenttype/{ctId}/fields/id/{fieldId}/variablesreturnsnewVar. ✅
- Confirm it saved:
- Switch to the Overview tab, change any property (e.g. type something into Hint), and click Save.
- Re-check the variables:
GET /api/v1/contenttype/{ctId}/fields/id/{fieldId}/variables
Expected: newVar is still there. The property save should not touch field variables.
Actual: newVar is gone. Count is 0. The property change itself saved correctly.
Reopening the Field Variables tab confirms the variable is missing from the UI as well.
Precise boundary of the bug (isolated during QA — useful for the fix):
| Scenario | Result |
|---|---|
| Variable existed at page load, then field properties saved | ✅ Survives — GET /api/v1/contenttype/id/{ctId} echoes fieldVariables populated, so the snapshot round-trips it correctly |
| Variable added in-session via the Field Variables tab, then field properties saved | ❌ Silently deleted |
So the trigger is specifically the staleness of the dialog's field snapshot, not the field save itself.
Acceptance Criteria
- A field variable added during a session survives a subsequent save of that field's properties.
- Saving a field's properties never deletes field variables that the user did not explicitly delete.
- Decide and implement the correct contract for
PUT /api/v3/contenttype/{ctId}/fields/{fieldId}: either the client must send a currentfieldVariablesarray, or the endpoint should ignorefieldVariableson a field update so a field PUT is not implicitly a variable-replacement operation. (The latter is more robust — a property update arguably should never be able to destroy variables.) - Regression coverage: add a variable, save field properties, assert the variable still exists.
dotCMS Version
Reproduced on dotcms/dotcms:trunk, build 1.0.0-SNAPSHOT — August 31, 2026 (latest main).
Believed to affect all recent versions — see Regression status.
Severity
High - Major functionality broken
(Silent, unwarned data loss. The user has no indication anything was destroyed, and no way to know to re-add it.)
Links
NA
Regression status — not introduced by #36341
Verified by code inspection rather than by booting a pre-fix build:
- The deleted
FieldService.updateFieldand the newDotFieldService.updateFieldissue the identicalPUT /api/v3/contenttype/{ctId}/fields/{fieldId}with{ field }. - The pre-refactor
saveFieldsHandlerdidObject.assign(this.currentField, fieldToSave)wherecurrentFieldcame fromthis.fieldRows— also a page-load snapshot, with the same staleness.
Neither the old nor the new code path refreshes the field object after a variable write, so this behavior almost certainly predates the refactor. Not confirmed against a pre-fix build.
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 by tracing PUT /api/v3/contenttype/{ctId}/fields/{fieldId} alongside POST /api/v1/contenttype/{ctId}/fields/id/{fieldId}/variables, using the supplied reproduction to confirm the stale fieldVariables payload. Add regression coverage that creates a variable, saves a field property, and verifies the variable remains present. Done means property saves no longer delete variables the user did not explicitly remove.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100