ciscoheat / sveltekit-superforms

Making SvelteKit forms a pleasure to use!
https://superforms.rocks
MIT License
2.26k stars 65 forks source link

Error in EnhancedForm_destroy - `Uncaught (in promise) TypeError: EnhancedForm.remove is not a function` #500

Open oscarhermoso opened 3 weeks ago

oscarhermoso commented 3 weeks ago

Description

I have a pretty dense SPA superform component that throws an error from EnhancedForm_destroy, because of Uncaught (in promise) TypeError: EnhancedForm.remove is not a function.

It seems that EnhancedForm is expected to be a HTMLElement with a remove() method. This is fine on Chrome.

However, on Firefox, there is no remove() method - I believe it is a DOM Node.

EDIT: I have reproduced on both Chrome and Firefox.

https://github.com/user-attachments/assets/61d3a860-0052-4913-81c2-088388ed0d66

The error is bubbling from here:

https://github.com/ciscoheat/sveltekit-superforms/blob/ae643b27e574b75a70adb7e3d2804befcfa3564e/src/lib/client/superForm.ts#L1395-L1400

https://github.com/ciscoheat/sveltekit-superforms/blob/ae643b27e574b75a70adb7e3d2804befcfa3564e/src/lib/client/superForm.ts#L542-L552

If applicable, a MRE

Apologies, I have attempted to reproduce in a minimal REPL, but I have been unable to.

Discovered error on sveltekit-superforms v2.12.3, attempted to upgrade to sveltekit-superforms, v2.19.1 and issue is still occurring.

Firefox version 126.0 (64-bit) Chrome Version 128.0.6613.137

oscarhermoso commented 3 weeks ago

Ok - I have figured out the root cause - but I believe that a fix still needs to be made to the sveltekit-superforms library.

Given below form, when this form was unmounted from the page, SuperForm attempted to call .destroy() on an element. However, something about having an input with attribute name="remove" caused it to break.

Renaming the input to have attribute name="removed" solved the problem (note the extra "d").

It would be good to have a fix - ideally, I don't think that the name of HTML elements should affect the inner workings of SuperForm.

See below the full code that was causing issues. Apologies, but it is still difficult for me to create an MRE.

Code

```svelte

People with access
  • {$page.data.session.user.firstName} {$page.data.session.user.lastName} (You)
  • {#each file.users as user, i (user.publicId)}
  • {user.firstName} {user.lastName} {#if file.access.sharing} {/if}
  • {/each}
{#if serverError}
{serverError}
{/if} ```

ciscoheat commented 3 weeks ago

Thank you for the report, but this is very strange, how can the attribute of an input element affect the parent DOM object of the element's form? I have never seen that before.

oscarhermoso commented 2 weeks ago

I am not sure why it is occurring, but I have found some time to create an MRE.

Steps to reproduce

  1. Open browser console
  2. Enter a username
  3. Click submit

Expected

User can be added/removed with the form (expected behaviour can be reproduced by commenting out <Form /> and uncommenting <FixedForm /> in +page.svelte)

Actual

If input has attribute name="remove", errors with:

Uncaught TypeError: node.remove is not a function
    at destroy_effect (chunk-7G4UXERQ.js:1371:12)
    at chunk-7G4UXERQ.js:1411:5
    at run_out_transitions (chunk-7G4UXERQ.js:1423:5)
    at pause_effect (chunk-7G4UXERQ.js:1410:3)
    at chunk-ORL7STRW.js:567:9
    at update_reaction (chunk-7G4UXERQ.js:1714:23)
    at update_effect (chunk-7G4UXERQ.js:1805:21)
    at process_effects (chunk-7G4UXERQ.js:1932:11)
    at flush_queued_root_effects (chunk-7G4UXERQ.js:1863:7)
    at process_deferred (chunk-7G4UXERQ.js:1894:3)

else if input has attribute bind:checked={$form.users[i].remove}, errors with:

chunk-7G4UXERQ.js?v=a0a9029d:1650 Uncaught TypeError: EnhancedForm.remove is not a function
    at EnhancedForm_destroy (sveltekit-superforms.js?v=a0a9029d:2053:20)
    at sveltekit-superforms.js?v=a0a9029d:1502:7
    at untrack (chunk-7G4UXERQ.js?v=a0a9029d:2098:12)
    at chunk-ORL7STRW.js?v=a0a9029d:2704:23
    at chunk-ORL7STRW.js?v=a0a9029d:2626:11
    at execute_effect_teardown (chunk-7G4UXERQ.js?v=a0a9029d:1326:17)
    at destroy_effect (chunk-7G4UXERQ.js?v=a0a9029d:1386:3)
    at destroy_effect_children (chunk-7G4UXERQ.js?v=a0a9029d:1347:5)
    at destroy_effect (chunk-7G4UXERQ.js?v=a0a9029d:1376:3)
    at destroy_effect_children (chunk-7G4UXERQ.js?v=a0a9029d:1347:5)

Note that it is quite inconsistent. I have found that I reproduce the error more consistently after spending more time in the error/making changes - so it may be related to local dev/HMR?