dotCMS / dotCMS/core

File editor rejects file names containing more than one period; Save silently fails when editing existing files

Open
#37,490 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

OKR : Customer Support Team : Maintenance
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Problem Statement

The code editor's file-name field validates against Validators.pattern(/^[^.]+.[^.]+$/), which permits exactly one period. Any file name with two or more — app.calculator.js, jquery.min.js, types.d.ts, tailwind.config.js — fails validation and cannot be saved.

The intended rule is "file name must have an extension." The regex implements "file name must have exactly one period." That gap is the whole defect, and it's provable from the component's own artifacts:

  • the only invalid-name test case is 'nodotextension' (dot-form-file-editor.component.spec.ts:237) — no test asserts a multi-period name is invalid;
  • the error message shown is dot.file.field.error.type.file.not.extension → "Please add the file's extension" — nonsensical for a file that has one;
  • extractFileExtension() in the same feature (utils/editor.ts:7) uses split('.').pop(), i.e. it explicitly handles multi-period names correctly.

There are two distinct user-visible faces:

Creating a new file — the name control is dirty (the user typed it), so the error renders. Save is blocked with the misleading "Please add the file's extension."
Editing an existing file — the name is populated via patchValue() in #initValuesForm(), leaving the control pristine. On submit, onSubmit() calls this.form.markAsDirty() on the FormGroup, which in Angular does not propagate to child controls. DotFieldValidationMessageComponent gates rendering on _field.dirty, so the message is suppressed entirely. The user gets a dead Save button with no feedback at all.

Uploading/importing bypasses this dialog and accepts any name. That is the only way a multi-period file enters the system — and once it exists, it can never be edited in place through the UI again. For customers with historic bundler output (*.min.js, dotted module names), every such asset is permanently read-only in the editor.

This is a second-order miss from #36543 / #36547: that fix corrected over-eager validation on the content control and explicitly left the name control's validation unchanged. Same symptom class (silent Save), different root cause, still open.

Not a regression. The validator has been unchanged since commit 0c1b222 (feat(edit-content): create new file functionality on File Fields #30391, 2024-10-24). It is present verbatim at tag v26.08.19-04.

Steps to Reproduce

Steps to Reproduce

https://drive.google.com/file/d/1957fTtd7Pxlr6h4fqndBQVcn3rRFv7t6/view?usp=sharing

Three scenarios. A is the customer-facing one; B is the cleanest demonstration; C shows why the file can exist at all.

A — Editing an existing multi-period file (silent failure)
Upload a JS file named app.calculator.js to any site (this succeeds — see C).
Open the containing contentlet and click the edit (pencil) action on the file field to open the code editor.
Change any character in the editor content.
Click Save.

Expected: the file saves.
Actual: nothing happens. Dialog stays open, no error message anywhere, no network request is issued. The file is unchanged.

B — Creating a new file with a multi-period name (misleading error)
On a File/Binary field, click Create new file.
Enter the name app.calculator.js.
Enter valid content, e.g. const a = 1; (use valid syntax so the unrelated Monaco syntax-error blocker from #36543 isn't also triggered).
Click Save.

Expected: the file is created.
Actual: the name field is outlined red with "Please add the file's extension" — on a file name that plainly has one. Save is refused.

C — Control: upload accepts the same name
Upload a file named app.calculator.js via drag-and-drop or the file picker.

Actual: succeeds. Confirms the platform accepts these names and the constraint exists only in this dialog. The resulting asset then cannot be edited via A.

Control: single-period names are unaffected

app-calculator.js works in all three flows.

Acceptance Criteria
  • A file name containing multiple periods (app.calculator.js, jquery.min.js, types.d.ts) passes name validation in the file editor.
  • Scenario A: an existing multi-period file can be edited and saved from the code editor.
  • Scenario B: a new file with a multi-period name can be created from the code editor.
  • A file name with no extension (nodotextension) is still rejected — the existing intended contract is preserved.
  • When Save is blocked by any name-field validation error, the error message is visible to the user. Specifically, submitting with a pristine, invalid name control must surface the message (i.e. onSubmit() marks the control dirty/touched, not just the FormGroup) — no silent dead button under any validation failure.
  • The dot.file.field.error.type.file.not.extension copy accurately describes the condition that actually triggered it.
  • Unit tests in dot-form-file-editor.component.spec.ts cover: multi-period name is valid; extensionless name is still invalid; a blocked submit with a pristine invalid name renders the error message.
  • Behaviour verified in both hosts the component runs in — the new Edit Content screen and the legacy Dojo editor (where it renders as the dotcms-binary-field custom element).
dotCMS Version

26.08.19-04 (Evergreen)

Severity

Medium - Some functionality impacted

Links

https://dotcms.freshdesk.com/a/tickets/39306

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the file editor component and dot-form-file-editor.component.spec.ts, especially the validation case at line 237 and the onSubmit()/#initValuesForm() paths described in the issue; compare them with extractFileExtension() in utils/editor.ts. Run the component tests and verify multi-period names work, extensionless names remain invalid, pristine invalid names show an error, and both editor hosts behave correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.