hacksider/Deep-Live-Cam · error · ValueError
embeddings must not be empty
Error message
embeddings must not be empty
What it means
ValueError raised by find_cluster_centroids in modules/cluster_analysis.py when the embeddings sequence passed in has length 0. The function needs at least one sample to fit sklearn KMeans, so it fails fast before touching KMeans rather than letting sklearn raise a less clear error. It is a pure input-contract error: the embeddings argument itself is empty, not malformed.
Source
Thrown at modules/cluster_analysis.py:9
import numpy as np
from sklearn.cluster import KMeans
from typing import Any
def find_cluster_centroids(embeddings, max_k=10) -> Any:
n_samples = len(embeddings)
if n_samples == 0:
raise ValueError("embeddings must not be empty")
if max_k < 1:
raise ValueError("max_k must be at least 1")
max_k = min(max_k, n_samples)
if max_k == 1:
kmeans = KMeans(n_clusters=1, random_state=0)
kmeans.fit(embeddings)
return kmeans.cluster_centers_
inertia = []
cluster_centroids = []
K = range(1, max_k+1)
for k in K:
kmeans = KMeans(n_clusters=k, random_state=0)
kmeans.fit(embeddings)
inertia.append(kmeans.inertia_)
cluster_centroids.append({"k": k, "centroids": kmeans.cluster_centers_})View on GitHub (pinned to 987f6b392b)
Solutions
- Check len(embeddings) > 0 at the call site before invoking find_cluster_centroids and skip/short-circuit clustering when there is nothing to cluster.
- Trace upstream: log the size of the embedding batch right after it is produced to find which stage emptied it.
- If an empty input is a legitimate case for your flow, handle it explicitly (return [] or skip clustering) instead of relying on the exception.
Example fix
// before
centroids = find_cluster_centroids(embeddings)
// after
if not embeddings:
return []
centroids = find_cluster_centroids(embeddings) Defensive patterns
Strategy: validation
Validate before calling
if not embeddings or len(embeddings) == 0:
# nothing to cluster; skip or return empty result
return []
centroids = find_cluster_centroids(embeddings) Type guard
def has_samples(embeddings) -> bool:
try:
return len(embeddings) > 0
except TypeError:
return False Try / catch
try:
centroids = find_cluster_centroids(embeddings)
except ValueError as e:
if "must not be empty" in str(e):
centroids = [] # explicit empty-policy, not a silent fallback
else:
raise Prevention
- Log embedding-batch size at the producing stage so empties are caught where they originate.
- Treat an empty batch as a skip condition in the pipeline, never forward it to clustering.
- Add a unit test calling find_cluster_centroids with [] to pin the contract.
When it happens
Trigger: Calling find_cluster_centroids([]), find_cluster_centroids(np.empty((0, 768))), or any embeddings list produced by a pipeline stage that returned zero items (e.g. all frames filtered out, zero faces detected, empty batch from a database query). len(embeddings) == 0 at function entry is the only trigger.
Common situations: Upstream embedding extraction silently returning an empty list; a filter step removing all candidates before clustering; first run of a pipeline on an empty dataset; passing a generator result that was already consumed; None-vs-[] confusion where an empty list is forwarded instead of aborting.
Related errors
- max_k must be at least 1
- {NAME}: Model not found at {model_path}
- {NAME}: Failed to load GFPGAN ONNX model: {e}
- {NAME}: Failed to initialize GFPGAN ONNX session. Check logs
- Model file not found: {model_path}
AI-assisted analysis of hacksider/Deep-Live-Cam@987f6b392b (2026-08-14).
Data as JSON: /api/errors/6784f8ef2eada040.
Report an issue: GitHub.