Editor V4: Atomic Form File Upload inside a Component silently discards the uploaded file (4.3.0-beta3)
Description
Elementor 4.3.0-beta3 + Elementor Pro 4.3.0-beta3, Editor V4, Atomic Form inside a Component.
When an Atomic Form lives inside a Component, a file chosen in its File Upload field is silently discarded on submit:
- the submission is reported as successful to the visitor and to every action (
collect-submissionssuccess,emailsuccess); - the stored submission has an empty value for the File Upload field;
- the email has no link and no attachment, whichever "Send file" mode is chosen (link / attach / both);
wp-content/uploads/elementor/forms/is never created and the temp upload is dropped;- nothing is logged, nothing is returned in the AJAX response. The only trace is the missing file.
If the File Upload field is marked Required, the visitor instead gets "This field is required." even though they did pick a file, so the form cannot be submitted at all.
The same form placed directly on a page (not inside a Component) uploads the file correctly.
This is a second, data-losing symptom of the id mismatch described in #37322 (merge tags resolving empty). That report covers build_cssid_map(); this one goes through a different code path, File_Upload_Handler, and is not mentioned there, so I am filing it separately so it gets tracked.
Root cause (beta3 source)
Each field inside a Component instance is rendered with two ids: data-id = instance-scoped id (regenerated per instance by the Components module, original kept in origin_id), data-interaction-id = the component's original element id.
elementor/assets/js/atomic-widgets-form-handler.jsposts the origin id for every field:const allInputs = [...form.querySelectorAll(ATOMIC_FORM_FIELD_SELECTOR)].filter((input) => input.dataset.interactionId); const id = input.dataset.interactionId; // -> form_fields[i][id]elementor-pro/modules/atomic-form/file-upload/field-settings-collector.phpwalks the expanded form element and keys the file field settings by the instance id:$map[ $element['id'] ] = Render_Props_Resolver::for_settings()->resolve( File_Upload::get_props_schema(), $element['settings'] ?? [] );File_Upload_Handler::process()buildsindex -> posted idfromform_fields, groups$_FILESby that posted (origin) id, then loops over the settings map (instance ids):The two id sets never intersect, so$field_files = $files_by_element_id[ $element_id ] ?? []; $validation_error = ( new Composite_Validator( $settings ) )->validate( $field_files ); ... if ( empty( $field_files ) ) { continue; }$field_filesis always empty: the file is never validated, never stored, never passed to$context['files'], andform_data_overridesstays empty. Withrequiredon,Required_Validatorreturns "This field is required." for the same reason.
Measured on one form (Contact form inside a Component):
| id | |
|---|---|
File Upload element in the expanded tree (Field_Settings_Collector key) |
1n678wt |
origin_id on that element / data-interaction-id in the markup / id posted by the browser |
71a1255d |
Submission recorded by collect-submissions for that request (values table):
4e83b91 Bugtest
1e5f159b FileDrop
3272abdf [email protected]
2581923a Triangle
71a1255d <- File Upload: empty, a 193-byte PDF was attached
27e01f63 YesAJAX response for the same request:
{"success":true,"data":{"message":"Your submission was successful.","data":{"actionResults":[{"type":"collect-submissions","status":"success","message":"Submission saved successfully","submissionId":6},{"type":"email","status":"success","message":"Email sent successfully"}],"allActionsSucceeded":true,"failedActions":[]}}}uploads/elementor/forms/ does not exist on the site after the submission.
Suggested fix: use one id on both sides. Either post data-id for the fields (the handler already uses form.dataset.id for the form itself), or have Field_Settings_Collector (and build_cssid_map()) key by origin_id when present, or remap posted ids via origin_id before processing. Whichever way, a file that was posted but matched no field should probably produce an error rather than a silent success.
Steps to reproduce
- Clean WordPress install, Hello Elementor 3.5.1, Elementor 4.3.0-beta3, Elementor Pro 4.3.0-beta3. Editor V4, Atomic Widgets and Atomic Form experiments active.
- In Editor V4 create an Atomic Form with a Text field, an Email field and a File Upload field (leave Required off, allowed types default, "Send file" = Email with link). Actions after submit: Collect Submissions + Email.
- Save the form as a Component and place the Component on a page. Publish.
- Open the page on the front end, fill in the fields, pick a small PDF or PNG in the File Upload field, submit.
- Observe the success message. Open Elementor > Submissions and the received email.
- Check
wp-content/uploads/elementor/forms/. - Control: put the same form directly on a page (not via the Component) and repeat steps 4 to 6.
Optional: DevTools > Network > admin-ajax.php shows form_fields[n][id] equal to the field's data-interaction-id, and form_fields[n][value][0] carrying the file.
Observed (inside Component): submission and email report success, the File Upload value is empty, the email has no link/attachment, uploads/elementor/forms/ is not created. Set the field to Required and the same submission is rejected with "This field is required.".
Observed (direct on page): file stored under uploads/elementor/forms/, link in the submission and email.
Expected behavior
A file chosen in a File Upload field is validated, stored and delivered (link or attachment) the same way whether the form is placed on the page directly or through a Component. If for any reason a posted file cannot be matched to a field, the submission should fail with an error instead of reporting success and dropping the file.
Elementor System Info
== Server Environment ==
Operating System: Linux
Software: nginx/1.31.3
MySQL version: mariadb.org binary distribution v11.4.12-MariaDB-ubu2404
PHP Version: 8.4.21
PHP Memory Limit: 1024M
PHP Max Input Vars: 10000
PHP Max Post Size: 128M
GD Installed: Yes
ZIP Installed: Yes
Write Permissions: All right
Elementor Library: Connected
== WordPress Environment ==
Version: 7.1.1
Site URL: [redacted]
Home URL: [redacted]
WP Multisite: No
Max Upload Size: 128 MB
Memory limit: 512M
Max Memory limit: 1024M
Permalink Structure: /%postname%/
Language: [redacted]
Timezone: [redacted]
Admin Email: [redacted]
Debug Mode: Inactive
== Theme ==
Name: Hello Elementor
Version: 3.5.1
Author: Elementor Team
Child Theme: No
== User ==
Role: administrator
WP Profile lang: [redacted]
User Agent: [redacted]
== Active Plugins ==
Advanced Custom Fields PRO
Version: 6.8.10
Author: WP Engine
Easy WP SMTP
Version: 2.15.1
Author: Easy WP SMTP
Elementor
Version: 4.3.0-beta3
Author: Elementor.com
Elementor Pro
Version: 4.3.0-beta3
Author: Elementor.com
EWWW Image Optimizer
Version: 8.7.7
Author: Exactly WWW
Rank Math SEO
Version: 1.0.278
Author: Rank Math SEO
Rank Math SEO PRO
Version: 3.0.121
Author: Rank Math SEO
Wordfence Security
Version: 9.0.1
Author: Wordfence
== Must-Use Plugins ==
None
== Elements Usage ==
archive : 1
e-component : 3
e-flexbox : 4
e-paragraph : 1
footer : 1
e-component : 1
e-flexbox : 1
header : 1
container : 5
e-button : 1
e-component : 2
e-div-block : 1
e-flexbox : 5
e-image : 1
e-paragraph : 1
e-svg : 2
mega-menu : 1
page : 1
e-component : 1
e-flexbox : 1
popup : 2
e-component : 3
e-flexbox : 3
wp-post : 0
e-button : 3
e-component : 13
e-div-block : 3
e-divider : 2
e-flexbox : 22
e-grid : 3
e-heading : 4
e-paragraph : 18
e-svg : 9
wp-page : 9
e-accordion : 5
e-accordion-item : 15
e-accordion-item-content : 15
e-accordion-item-header : 15
e-accordion-item-icon : 3
e-accordion-item-title : 15
e-button : 27
e-collection-loop : 1
e-collection-loop-item : 1
e-collection-loop-layout : 1
e-component : 31
e-divider : 10
e-flexbox : 140
e-grid : 11
e-heading : 105
e-paragraph : 174
e-self-hosted-video : 1
e-svg : 39
e-tab : 15
e-tab-content : 15
e-tabs : 5
e-tabs-content-area : 5
e-tabs-menu : 5
e-youtube : 1
single-post : 1
e-component : 3
e-flexbox : 4
e-paragraph : 1
theme-post-content : 1
error-404 : 1
e-component : 1
e-flexbox : 1
== Settings ==
cpt_support: post, page
disable_color_schemes: yes
disable_typography_schemes: yes
allow_tracking: no
unfiltered_files_upload: 1
font_display: swap
meta_generator_tag: 1
disabled_elements: inner-section, heading, image, video, button, divider, spacer, image-box, google_maps, icon-box, image-carousel, image-gallery, counter, progress, testimonial, alert, audio, shortcode, menu-anchor, sidebar, read-more, rating, wp-widget-pages, wp-widget-calendar, wp-widget-archives, wp-widget-media_audio, wp-widget-media_image, wp-widget-media_gallery, wp-widget-media_video, wp-widget-meta, wp-widget-search, wp-widget-text, wp-widget-categories, wp-widget-recent-posts, wp-widget-recent-comments, wp-widget-rss, wp-widget-tag_cloud, wp-widget-nav_menu, wp-widget-custom_html, wp-widget-block, text-path, link-in-bio, theme-site-logo, theme-site-title, theme-page-title, theme-post-title, theme-post-excerpt, theme-post-featured-image, theme-archive-title, archive-posts, off-canvas, posts, portfolio, gallery, login, slides, animated-headline, hotspot, price-list, price-table, flip-box, call-to-action, media-carousel, testimonial-carousel, reviews, table-of-contents, countdown, share-buttons, author-box, post-comments, post-navigation, post-info, sitemap, blockquote, facebook-embed, facebook-page, lottie, code-highlight, video-playlist, paypal-button, progress-tracker, nested-carousel, link-in-bio-var-2, link-in-bio-var-3, link-in-bio-var-5, link-in-bio-var-6, link-in-bio-var-7, link-in-bio-var-4, form, nested-tabs, html, breadcrumbs, loop-grid, taxonomy-filter, template, stripe-button, social-icons, nav-menu, icon, icon-list, nested-accordion, loop-carousel
== Features ==
Custom Fonts: 2
Custom Icons: 0
== Integrations ==
== Elementor Experiments ==
Inline Font Icons: Active by default
Additional Custom Breakpoints: Active by default
Container: Active by default
Optimized Markup: Active by default
Optimized CSS Files: Inactive by default
Default to New Theme Builder: Active by default
Header & Footer: Inactive
Nested Elements: Active by default
Pages Panel: Inactive by default
Atomic Widgets: Active by default
List: Inactive by default
Icon Button: Inactive by default
Accordion: Inactive by default
SVG Library: Inactive by default
Launchpad Checklist: Inactive by default
Page Audit: Inactive by default
Editor V4: Active by default
Component Variants: Inactive by default
Angie in editor panels: Inactive by default
Generate website markdown: Inactive by default
Agents llms.txt: Inactive by default
Dynamic Assets Management: Inactive by default
Import/Export Customization: Active by default
Atomic Form: Active by default
Loop: Active by default
Menu: Active by default
In-Editor Feedback: Inactive by default
Elementor Editor Events: Active by default
== Log ==
PHP: showing 4 of 4
PHP: 2026-09-12 18:09:27 [warning X 30][[path]/plugins/elementor/modules/interactions/interactions-frontend-handler.php::61] foreach() argument must be of type array|object, null given
PHP: 2026-09-12 18:21:08 [notice X 150][[path]/plugins/elementor/modules/global-classes/atomic-global-styles.php::410] Elementor\Modules\GlobalClasses\Atomic_Global_Styles::get_cache_root_key(): Implicitly marking parameter $key as nullable is deprecated, the explicit nullable type must be used instead
PHP: 2026-09-12 18:53:21 [warning X 8][[path]/plugins/elementor/modules/history/revisions-manager.php::363] Undefined array key "editor_post_id"
PHP: 2026-09-18 15:04:44 [error X 1][[path]/plugins/elementor/core/settings/manager.php::149] Uncaught Error: Call to a member function get_tabs_controls() on null in [path]/plugins/elementor/core/settings/manager.php:149
JS: showing 3 of 3
JS: 2026-09-12 08:38:36 [error X 91][elementor-pro/assets/js/editor.min.js?ver=4.3.0-beta2:2:103668] Cannot read properties of undefined (reading 'find')
JS: 2026-09-12 08:38:49 [error X 30][elementor/assets/js/editor.min.js?ver=4.3.0-beta2:9:22126] Failed to execute 'querySelector' on 'Document': '#' is not a valid selector.
JS: 2026-09-17 02:37:00 [error X 27][elementor/assets/js/editor-modules.min.js?ver=4.3.0-beta2:6:9016] Cannot read properties of null (reading 'editor')
Log: showing 10 of 10
2026-09-20 10:19:07 [info] Elementor data updater process has been queued. (Elementor 4.3.0-beta2 -> 4.3.0-beta3)
2026-09-20 10:20:16 [info] elementor::elementor_updater Started
2026-09-20 10:20:16 [info] Elementor/Upgrades - _on_each_version Start
2026-09-20 10:20:16 [info] Elementor/Upgrades - _on_each_version Finished
2026-09-20 10:20:16 [info] Elementor data updater process has been completed. (Elementor 4.3.0-beta2 -> 4.3.0-beta3)
2026-09-20 12:02:35 [info] Elementor data updater process has been queued. (Elementor Pro 4.3.0-beta2 -> 4.3.0-beta3)
2026-09-20 12:04:00 [info] elementor-pro::elementor_pro_updater Started
2026-09-20 12:04:00 [info] Elementor Pro/Upgrades - _on_each_version Start
2026-09-20 12:04:00 [info] Elementor Pro/Upgrades - _on_each_version Finished
2026-09-20 12:04:00 [info] Elementor data updater process has been completed. (Elementor Pro 4.3.0-beta2 -> 4.3.0-beta3)
== Elementor - Compatibility Tag ==
Elementor Pro: Compatibility not specified
== Elementor Pro - Compatibility Tag ==
Agreement
- I confirm I have read and followed all the guidelines and instructions outlined in the Editor V4 Bug Report form.
- I agree that my issue may be closed without further action if it doesn't meet all the requirements outlined in the Editor V4 Bug Report form.
Source: elementor/elementor