diff --git a/program/migrations/0126_playlistentry_file_id_or_uri.py b/program/migrations/0126_playlistentry_file_id_or_uri.py
new file mode 100644
index 0000000000000000000000000000000000000000..d50754321bf39e9b9425e9ef013ea2152f949fbd
--- /dev/null
+++ b/program/migrations/0126_playlistentry_file_id_or_uri.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.2.16 on 2024-11-12 19:27
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ("program", "0125_alter_playlistentry_duration"),
+    ]
+
+    operations = [
+        migrations.AddConstraint(
+            model_name="playlistentry",
+            constraint=models.CheckConstraint(
+                check=models.Q(
+                    ("file_id__isnull", False),
+                    models.Q(("uri", ""), _negated=True),
+                    _connector="OR",
+                ),
+                name="file-id-or-uri",
+            ),
+        ),
+    ]
diff --git a/program/models.py b/program/models.py
index a3df5d49b4ca2053ef3e4f8211426c46f07a5f4c..55d4033050c129111fb6b01d36b9fc91f4616d1d 100644
--- a/program/models.py
+++ b/program/models.py
@@ -619,6 +619,14 @@ class PlaylistEntry(models.Model):
     playlist = models.ForeignKey(Playlist, on_delete=models.CASCADE, related_name="entries")
     uri = models.CharField(blank=True, max_length=1024)
 
+    class Meta:
+        constraints = [
+            models.CheckConstraint(
+                check=Q(file_id__isnull=False) | ~Q(uri=""),
+                name="file-id-or-uri",
+            )
+        ]
+
     def __str__(self):
         return f"{self.uri} - {self.duration}" if self.duration else self.uri