dioxus icon indicating copy to clipboard operation
dioxus copied to clipboard

Uncaught DOMException: Element.before: The new child is an ancestor of the parent

Open brianmay opened this issue 7 months ago • 5 comments

Problem

With my open source code: https://github.com/brianmay/penguin_nurse

If I try to search for a consumable, e.g.:

  1. Click "Consumables"
  2. Focus on "Search" text field.
  3. Press N, works.
  4. Press U. works.
  5. Press T, works.
  6. Press S, entire page is replaced with black screen, and Firefox logs following error:
Uncaught DOMException: Element.before: The new child is an ancestor of the parent
    run https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:1
    __wbg_run_b869ac02fd3748d0 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    __wbg_adapter_62 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    real https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:1
    __wbg_queueMicrotask_97d92b4fcc8a61c5 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    __wbg_adapter_62 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    real https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:1
    promise callback*__wbg_get_imports/imports.wbg.__wbg_then_48b406749878a531 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    __wbg_adapter_62 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    real https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:1
    __wbg_queueMicrotask_97d92b4fcc8a61c5 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    __wbg_adapter_62 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    real https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:1
    promise callback*__wbg_get_imports/imports.wbg.__wbg_then_48b406749878a531 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    __wbg_adapter_62 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
    real https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:1
    __wbg_queueMicrotask_97d92b4fcc8a61c5 https://nurse.linuxpenguins.xyz/assets/penguin_nurse-20c672d692c2467b.js:2
penguin_nurse-20c672d692c2467b.js:1

Which is weird, makes it seem like I am doing something dodgy with the DOM. But I am only using Dioxus components.

Unfortunately, I have only been able to reproduce this on my prod server at present, still trying to get this to crash on a dev instance.

And there is another part of the code that does the same database search, only it works fine for the same searches.

I considered the possibility that there is bad data in the database, but the fact is every entry shown by the "NUTS" search is also shown by the "NUT" search. And I have also looked at the same search results using psql, and not seen anything obviously wrong.

Oh, and Chrome based browser (brave) crashes in the exact same way, but message is Chrome version:

Uncaught HierarchyRequestError: Failed to execute 'before' on 'Element': The new child element contains the parent.
    at RawInterpreter.run (penguin_nurse-20c672d692c2467b.js:1:10927)
    at imports.wbg.__wbg_run_b869ac02fd3748d0 (penguin_nurse-20c672d692c2467b.js:2:31108)
    at penguin_nurse_bg-58b6f91390bdb813.wasm:0x21aea7
    at penguin_nurse_bg-58b6f91390bdb813.wasm:0x9a70f
    at penguin_nurse_bg-58b6f91390bdb813.wasm:0x25d69b
    at penguin_nurse_bg-58b6f91390bdb813.wasm:0x2f336e
    at penguin_nurse_bg-58b6f91390bdb813.wasm:0x2f3360
    at penguin_nurse_bg-58b6f91390bdb813.wasm:0x2f5935
    at __wbg_adapter_62 (penguin_nurse-20c672d692c2467b.js:2:1081)
    at real (penguin_nurse-20c672d692c2467b.js:1:22773)
run @ penguin_nurse-20c672d692c2467b.js:1
imports.wbg.__wbg_run_b869ac02fd3748d0 @ penguin_nurse-20c672d692c2467b.js:2
$func723 @ penguin_nurse_bg-58b6f91390bdb813.wasm:0x21aea7
$func384 @ penguin_nurse_bg-58b6f91390bdb813.wasm:0x9a70f
$func1116 @ penguin_nurse_bg-58b6f91390bdb813.wasm:0x25d69b
$func3053 @ penguin_nurse_bg-58b6f91390bdb813.wasm:0x2f336e
$func3052 @ penguin_nurse_bg-58b6f91390bdb813.wasm:0x2f3360
$closure2872_externref_shim @ penguin_nurse_bg-58b6f91390bdb813.wasm:0x2f5935
__wbg_adapter_62 @ penguin_nurse-20c672d692c2467b.js:2
real @ penguin_nurse-20c672d692c2467b.js:1

Mobile browsers also do the same thing.

Will keep trying to investigate, but this has me stumped.

There is no reason I can think of why the child should contain the parent.

Steps To Reproduce

As above.

Expected behavior

Should not crash the browser JavaScript.

Environment:

  • Dioxus version: 0.6.3
  • Rust version: 1.86.0 (05f9846f8 2025-03-31)
  • OS info: NixOs 24.11
  • App platform: web / full stack

Questionnaire

brianmay avatar Apr 30 '25 21:04 brianmay

This is making me nuts.

I copy the 'consumables' table from prod to dev and now dev crashes.

I make a dummy update on the database, and it comes good. Even though nothing changed.

Then I copy the table again from my prod server and it starts crashing again. Even though essentially nothing changed.

I have dumped the data in various places and confirmed it is exactly the same.

I have noticed it is more likely to crash if you type in the letters slowly. If I artificially add a 1 second delay in the sleep, and I type in "NUTS" fast so there is only one update, it is more likely to work. Which is the exact opposite of what I was expecting. Then if I push backspace to get "NUT" it crashes.

It does seems like the transition from "NUT" to "NUTS" or "NUTS" to "NUT" is what is causing it to crash.

This is literally and figuratively nuts.

brianmay avatar May 01 '25 00:05 brianmay

It seems to be related to having a conditional as the top level in a component in a loop. This will cause it to crash.

                    table { class: "block sm:table",
                        thead { class: "hidden sm:table-header-group",
                            tr {
                                th { "Name" }
                                th { "Brand" }
                                th { "Unit" }
                                th { "Ingredients" }
                                th { "Comments" }
                                th { "Created" }
                                th { "Destroyed" }
                            }
                        }
                        tbody { class: "block sm:table-row-group",
                            for consumable in list.iter() {
                                EntryRow {
                                    key: "{consumable.consumable.id.as_inner().to_string()}",
                                    consumable_with_items: consumable.clone(),
                                    selected,
                                    dialog,
                                }
                            }
                       }

[...]

#[component]
fn EntryRow(
    consumable_with_items: ConsumableWithItems,
    dialog: Signal<ActiveDialog>,
    selected: Signal<Option<ConsumableId>>,
) -> Element {
    rsx! {
        if true == false {

        }
    }
}

If I do any of the following it stops it from crashing:

  • delete the dummy condition.
  • Put the dummy condition inside a div { ... }
  • Delete the key value. (I suspected maybe the key value was broken or duplicated but doesn't appear to be the case).
  • put {} before the EntryRow. I am guessing this might be similar to deleting the key value.

If I had the option I would consider putting the EntryRow inside a another element. That would fix the problem. But unfortunately, that breaks the html, my EntryRow could return two tr, and I think there is no valid html element you can put a tr in except for the tbody.

So I might just delete the key value for now. Not nice, but at least it stops the crashing.

brianmay avatar May 06 '25 02:05 brianmay

I also just ran into this with Dioxus v0.6.3. I have a list of rendered components with keys. The rendered components normally render a single element. When I try to add a conditional render after the element in the component, I get this same error.

Here's a rough example:

#[component]
fn Grid(items: Vec<Item>) -> Element {
    rsx! {
        div {
            for item in items {
                GridItem {
                    key: item.key(),
                    item,
                }
            }
        }
    }
}

#[component]
fn GridItem(item: Item) -> Element {
    rsx! {
        div { ... }
        if item.selected { // introducing this causes the crash
            div { ... }
        }
    }
}

I tried some of the workarounds @brianmay suggested and got the same results. Adding Fragment {} in the loop just before GridItem prevents the error, as does removing the key prop.

dbeckwith avatar Dec 06 '25 15:12 dbeckwith

That sounds similar to https://github.com/DioxusLabs/dioxus/pull/4929. Can you try a version of dioxus after that commit?

ealmloff avatar Dec 09 '25 14:12 ealmloff

Looks like this is in 0.7.2 (and 0.7.1 also); I should be able to test this again soon, time permitting :-)

brianmay avatar Dec 09 '25 20:12 brianmay

In my code I removed the "key" value, to get it working.

If I put the key value back in, it starts crashing again, this is with 0.7.2. The error looks similar to what I posted above.

brianmay avatar Dec 11 '25 23:12 brianmay