diff --git a/Cargo.lock b/Cargo.lock
index aea58177e094..8bd202cacba9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5281,7 +5281,6 @@ dependencies = [
  "same-file",
  "schemars",
  "serde",
- "serde-untagged",
  "tempfile",
  "thiserror",
  "tokio",
diff --git a/crates/uv-distribution/src/metadata/requires_dist.rs b/crates/uv-distribution/src/metadata/requires_dist.rs
index e1b1d763d4ea..730c287b1eba 100644
--- a/crates/uv-distribution/src/metadata/requires_dist.rs
+++ b/crates/uv-distribution/src/metadata/requires_dist.rs
@@ -278,7 +278,8 @@ mod test {
           |
         8 | tqdm = true
           |        ^^^^
-        invalid type: boolean `true`, expected an array or map
+        invalid type: boolean `true`, expected a single source (as a map) or list of sources
+
         "###);
     }
 
@@ -301,7 +302,6 @@ mod test {
         8 | tqdm = { git = "https://github.com/tqdm/tqdm", rev = "baaaaaab", tag = "v1.0.0" }
           |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         expected at most one of `rev`, `tag`, or `branch`
-
         "###);
     }
 
@@ -319,10 +319,10 @@ mod test {
         "#};
 
         assert_snapshot!(format_err(input).await, @r###"
-        error: TOML parse error at line 8, column 8
+        error: TOML parse error at line 8, column 48
           |
         8 | tqdm = { git = "https://github.com/tqdm/tqdm", ref = "baaaaaab" }
-          |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+          |                                                ^^^
         unknown field `ref`, expected one of `git`, `subdirectory`, `rev`, `tag`, `branch`, `url`, `path`, `editable`, `index`, `workspace`, `marker`
         "###);
     }
@@ -399,14 +399,12 @@ mod test {
         "#};
 
         assert_snapshot!(format_err(input).await, @r###"
-        error: TOML parse error at line 8, column 8
+        error: TOML parse error at line 8, column 16
           |
         8 | tqdm = { url = "§invalid#+#*Ä" }
-          |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+          |                ^^^^^^^^^^^^^^^^^
         invalid value: string "§invalid#+#*Ä", expected relative URL without a base
 
-
-        in `url`
         "###);
     }
 
diff --git a/crates/uv-workspace/Cargo.toml b/crates/uv-workspace/Cargo.toml
index 040f9fe068ba..967a90ae3ff4 100644
--- a/crates/uv-workspace/Cargo.toml
+++ b/crates/uv-workspace/Cargo.toml
@@ -37,7 +37,6 @@ rustc-hash = { workspace = true }
 same-file = { workspace = true }
 schemars = { workspace = true, optional = true }
 serde = { workspace = true, features = ["derive"] }
-serde-untagged = { workspace = true }
 thiserror = { workspace = true }
 tokio = { workspace = true }
 toml =  { workspace = true }
diff --git a/crates/uv-workspace/src/pyproject.rs b/crates/uv-workspace/src/pyproject.rs
index c72a3d7d5187..605a6e6f7df4 100644
--- a/crates/uv-workspace/src/pyproject.rs
+++ b/crates/uv-workspace/src/pyproject.rs
@@ -8,6 +8,7 @@
 
 use glob::Pattern;
 use owo_colors::OwoColorize;
+use serde::de::SeqAccess;
 use serde::{de::IntoDeserializer, Deserialize, Deserializer, Serialize};
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
@@ -502,10 +503,37 @@ impl<'de> serde::de::Deserialize<'de> for SourcesWire {
     where
         D: Deserializer<'de>,
     {
-        serde_untagged::UntaggedEnumVisitor::new()
-            .map(|map| map.deserialize().map(SourcesWire::One))
-            .seq(|seq| seq.deserialize().map(SourcesWire::Many))
-            .deserialize(deserializer)
+        struct Visitor;
+
+        impl<'de> serde::de::Visitor<'de> for Visitor {
+            type Value = SourcesWire;
+
+            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+                formatter.write_str("a single source (as a map) or list of sources")
+            }
+
+            fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+            where
+                A: SeqAccess<'de>,
+            {
+                let sources = serde::de::Deserialize::deserialize(
+                    serde::de::value::SeqAccessDeserializer::new(seq),
+                )?;
+                Ok(SourcesWire::Many(sources))
+            }
+
+            fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
+            where
+                M: serde::de::MapAccess<'de>,
+            {
+                let source = serde::de::Deserialize::deserialize(
+                    serde::de::value::MapAccessDeserializer::new(&mut map),
+                )?;
+                Ok(SourcesWire::One(source))
+            }
+        }
+
+        deserializer.deserialize_any(Visitor)
     }
 }