{"record":{"id":"512cdb657280f25d","repo":"DioxusLabs/dioxus","slug":"body-element-to-exist","errorCode":null,"errorMessage":"Body element to exist","messagePattern":"Body element to exist","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/desktop/src/protocol.rs","lineNumber":129,"sourceCode":"    // If the request is for the root, we'll serve the index.html file.\n    if request.uri().path() != \"/\" {\n        return None;\n    }\n\n    // Load a custom index file if provided\n    let mut index = custom_index.unwrap_or_else(|| DEFAULT_INDEX.to_string());\n\n    // Insert a custom head if provided\n    // We look just for the closing head tag. If a user provided a custom index with weird syntax, this might fail\n    if let Some(head) = custom_head {\n        index.insert_str(index.find(\"</head>\").expect(\"Head element to exist\"), &head);\n    }\n\n    // Inject our module loader by looking for a body tag\n    // A failure mode here, obviously, is if the user provided a custom index without a body tag\n    // Might want to document this\n    index.insert_str(\n        index.find(\"</body>\").expect(\"Body element to exist\"),\n        &module_loader(root_name, headless, edit_state),\n    );\n\n    Response::builder()\n        .header(\"Content-Type\", \"text/html\")\n        .header(\"Access-Control-Allow-Origin\", \"*\")\n        .body(index.into())\n        .ok()\n}\n\n/// Construct the inline script that boots up the page and bridges the webview with rust code.\n///\n/// The arguments here:\n/// - root_name: the root element (by Id) that we stream edits into\n/// - headless: is this page being loaded but invisible? Important because not all windows are visible and the\n///   interpreter can't connect until the window is ready.\n/// - port: the port that the websocket server is listening on for edits\n/// - webview_id: the id of the webview that we're loading this into. This is used to differentiate between","sourceCodeStart":111,"sourceCodeEnd":147,"githubUrl":"https://github.com/DioxusLabs/dioxus/blob/393d190a801ccb441d41923e232289b4f8a5c669/packages/desktop/src/protocol.rs#L111-L147","documentation":"The desktop protocol injects its JS module loader immediately before `</body>`; find(\"</body>\").expect(\"Body element to exist\") panics when the served index.html has no exact closing body tag. Unlike the head check, this runs on every root request regardless of custom_head.","triggerScenarios":"Supplying a custom index via with_custom_index (or the configured index.html) that lacks `</body>` - e.g. only a fragment like `<div id=\"main\"></div>` - or uses a case-mismatched `</BODY>`.","commonSituations":"Replacing index.html with a partial snippet; minified/templated HTML where the body tag got mangled; assuming the framework will wrap fragments automatically.","solutions":["Include a complete HTML document with `<body>...</body>` in the custom index","Ensure the literal lowercase `</body>` is present; the lookup is case-sensitive","Remove the custom index to fall back to dioxus's built-in default index"],"exampleFix":"// before\n.with_custom_index(\"<div id='main'></div>\".into())\n\n// after\n.with_custom_index(\"<!DOCTYPE html><html><head></head><body><div id='main'></div></body></html>\".into())","handlingStrategy":"validation","validationCode":"fn index_has_body(index: &str) -> bool { index.contains(\"</body>\") }\n\nlet html = std::fs::read_to_string(\"index.html\").unwrap();\nassert!(index_has_body(&html), \"custom index must contain </body>\");","typeGuard":"fn is_valid_custom_index(index: &str) -> bool {\n    index.contains(\"</body>\") && index.contains(\"</head>\")\n}","tryCatchPattern":null,"preventionTips":["Never pass HTML fragments as with_custom_index - use a full document","Smoke-test the app startup after every custom index change","Remember both tag lookups are exact, case-sensitive string matches"],"tags":["desktop","index-html","config","panic","runtime"],"backgroundTag":null,"analyzedSha":"393d190a801ccb441d41923e232289b4f8a5c669","analyzedAt":"2026-08-16T11:27:45.815Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}