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

  1. Check len(embeddings) > 0 at the call site before invoking find_cluster_centroids and skip/short-circuit clustering when there is nothing to cluster.
  2. Trace upstream: log the size of the embedding batch right after it is produced to find which stage emptied it.
  3. 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

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


AI-assisted analysis of hacksider/Deep-Live-Cam@987f6b392b (2026-08-14). Data as JSON: /api/errors/6784f8ef2eada040. Report an issue: GitHub.