calesthio/OpenMontage · error · ValueError

diversify requires 'candidate_ids'

Error message

diversify requires 'candidate_ids'

What it means

Raised by _op_diversify when inputs['candidate_ids'] is missing, None, or an empty list. diversify picks a mutually-dissimilar subset from a candidate list you supply; with no candidates there is nothing to select.

Source

Thrown at tools/video/clip_search.py:333

        n=int(inputs.get("n", 5)),
        diversity=float(inputs.get("diversity", 0.3)),
        candidate_pool=int(inputs.get("candidate_pool", 30)),
        exclude_ids=inputs.get("exclude_ids") or [],
    )
    return {
        "seed_clip_id": seed,
        "results": [
            {"score": score, "record": asdict(rec)}
            for rec, score in results
        ],
    }


def _op_diversify(corp, inputs: dict[str, Any]) -> dict[str, Any]:
    """Pick the most mutually-dissimilar subset of a candidate list."""
    candidate_ids = inputs.get("candidate_ids") or []
    if not candidate_ids:
        raise ValueError("diversify requires 'candidate_ids'")

    kept = corp.diversify(
        candidate_ids=list(candidate_ids),
        n=int(inputs.get("n", 5)),
        diversity=float(inputs.get("diversity", 0.5)),
    )
    return {
        "input_count": len(candidate_ids),
        "kept_count": len(kept),
        "kept_ids": kept,
    }


def _op_get(corp, inputs: dict[str, Any]) -> dict[str, Any]:
    """Look up one clip_id and return its full record."""
    clip_id = inputs.get("clip_id")
    if not clip_id:
        raise ValueError("get requires 'clip_id'")

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Forward the ids from your retrieval step: [r['record']['clip_id'] for r in rank_results['results']]
  2. If the list can be empty, short-circuit before calling diversify (there is nothing to diversify)
  3. Check the exact key name candidate_ids (not ids/clip_ids)

Example fix

# before
result = clip_search.run(inputs={'operation':'diversify','n':5})

# after
ids = [r['record']['clip_id'] for r in ranked['results']]
result = clip_search.run(inputs={'operation':'diversify','candidate_ids':ids,'n':5})
Defensive patterns

Strategy: validation

Validate before calling

candidates = [r['record']['clip_id'] for r in (ranked.get('results') or [])]
if not candidates:
    raise ValueError('no candidates to diversify — earlier retrieval returned nothing')
inputs['candidate_ids'] = candidates

Type guard

def valid_candidates(inputs: dict) -> bool:
    c = inputs.get('candidate_ids')
    return isinstance(c, list) and len(c) > 0

Try / catch

try:
    result = clip_search.run(inputs=inputs)
except ValueError as e:
    if 'candidate_ids' in str(e):
        raise SystemExit('diversify needs a non-empty candidate list') from e
    raise

Prevention

When it happens

Trigger: Calling operation='diversify' standalone with no list; passing candidates under 'ids' or 'clip_ids'; a preceding rank_for_slot step returning zero results so the mapped candidate list is empty.

Common situations: Pipeline wiring where the candidate list comes from an earlier retrieval that can legitimately return empty; agent forgetting to forward the results of the previous tool call.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/4a51bc81de554c1f. Report an issue: GitHub.