diff --git a/helix-term/src/commands/typed.rs b/helix-term/src/commands/typed.rs
index 07374f77..9661689c 100644
--- a/helix-term/src/commands/typed.rs
+++ b/helix-term/src/commands/typed.rs
@@ -415,7 +415,7 @@ fn trim_final_newlines(doc: &mut Document, view_id: ViewId) {
 /// Ensure that the document is terminated with a line ending.
 fn insert_final_newline(doc: &mut Document, view_id: ViewId) {
     let text = doc.text();
-    if line_ending::get_line_ending(&text.slice(..)).is_none() {
+    if text.len_chars() > 0 && line_ending::get_line_ending(&text.slice(..)).is_none() {
         let eof = Selection::point(text.len_chars());
         let insert = Transaction::insert(text, &eof, doc.line_ending.as_str().into());
         doc.apply(&insert, view_id);
diff --git a/helix-term/tests/test/commands/write.rs b/helix-term/tests/test/commands/write.rs
index 38ab643c..f7123f68 100644
--- a/helix-term/tests/test/commands/write.rs
+++ b/helix-term/tests/test/commands/write.rs
@@ -482,6 +482,21 @@ async fn test_write_insert_final_newline_added_if_missing() -> anyhow::Result<()
     Ok(())
 }
 
+#[tokio::test(flavor = "multi_thread")]
+async fn test_write_insert_final_newline_unchanged_if_empty() -> anyhow::Result<()> {
+    let mut file = tempfile::NamedTempFile::new()?;
+    let mut app = helpers::AppBuilder::new()
+        .with_file(file.path(), None)
+        .with_input_text("#[|]#")
+        .build()?;
+
+    test_key_sequence(&mut app, Some(":w<ret>"), None, false).await?;
+
+    helpers::assert_file_has_content(&mut file, "")?;
+
+    Ok(())
+}
+
 #[tokio::test(flavor = "multi_thread")]
 async fn test_write_insert_final_newline_unchanged_if_not_missing() -> anyhow::Result<()> {
     let mut file = tempfile::NamedTempFile::new()?;