affaan-m/ECC · error · SystemExit

no readable references - nothing to mint

Error message

no readable references - nothing to mint

What it means

mint() accumulates pooled pixel arrays and cadence data from each readable reference video. If none of the references yielded readable frames (pooled_pixels is empty), it raises SystemExit('no readable references - nothing to mint'), since grading and cadence analysis require at least one decodable frame.

Solutions

  1. Verify each reference path exists and is a non-empty, decodable video (ffprobe each file).
  2. Re-transcode problem references to a standard codec: ffmpeg -i in.mov -c:v libx264 -pix_fmt yuv420p out.mp4.
  3. Install ffmpeg/codec support (e.g. opencv-python with ffmpeg, not a headless build without codecs) in the environment.
  4. Update the reference manifest/paths if the files were moved or renamed.
  5. Add logging in the reference loop to see per-file export failures and skip/replace bad refs.

Example fix

// before
refs = ["refs/a.mov", "refs/b.mov"]  # both unreadable

// after
for r in refs:
    if not Path(r).exists() or Path(r).stat().st_size == 0:
        raise SystemExit(f"bad reference: {r}")
subprocess.run(["ffmpeg", "-v", "error", "-i", r, "-f", "null", "-"], check=True)  # sanity decode
Defensive patterns

Strategy: validation

Validate before calling

import subprocess
for ref in refs:
    r = subprocess.run(["ffprobe", "-v", "error", ref], capture_output=True)
    if r.returncode != 0:
        raise SystemExit(f"unreadable reference: {ref}: {r.stderr.decode()[:200]}")

Type guard

def is_readable_video(path) -> bool:
    from pathlib import Path
    p = Path(path)
    return p.is_file() and p.stat().st_size > 0

Try / catch

try:
    mint(refs, out_dir)
except SystemExit as exc:
    if "no readable references" in str(exc):
        log.error("all references failed to decode; check codecs/paths: %s", refs)
    raise

Prevention

When it happens

Trigger: mint() loops over references calling frame_mod.export_stills; every reference fails to decode (missing file, corrupt/unsupported codec, unreadable path), so pooled_pixels stays empty and the raise fires after the loop.

Common situations: Reference videos are corrupt, zero-byte, or in a codec OpenCV/ffmpeg build cannot decode; reference paths are wrong or files were moved; running in a container without video codecs; all refs point at audio-only files.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16). Data as JSON: /api/errors/8c478dcbcf538e9f. Report an issue: GitHub.

Appendix: source

Thrown at skills/taste-distillation/scripts/mint.py:86

            pooled_pixels.append(np.concatenate([f.reshape(-1, 3) for f in fr]))
            noise_frames.extend(fr[:8])

        pooled_frames.append(fr)

        c = cad_mod.detect(ref_path)
        cadences.append(c)
        print(f"      {c.n_shots} shots, mean {c.mean_shot:.2f}s, {c.cuts_per_min:.0f} cuts/min")

        # Stills come from the longest shots of each reference, spread across
        # the whole set rather than taken from whichever ref happens to be first.
        ts = cad_mod.keyframe_timestamps(c, limit=max(1, max_stills // max(1, len(refs))))
        wrote = frame_mod.export_stills(ref_path, sp.stills_dir, ts, prefix=ref_id)
        print(f"      {len(wrote)} stills")

        sp.add_ref(ref_id, str(ref_path), c.total_duration, c.n_shots)

    if not pooled_pixels:
        raise SystemExit("no readable references - nothing to mint")

    print("  analyzing grade across pooled frames ...")
    stacked = np.concatenate(pooled_pixels, axis=0)
    g = grade_mod.analyze_pixels(stacked, noise_frames=noise_frames)
    merged = cad_mod.merge(cadences)

    print(f"  baking {lut_size}^3 LUT ...")
    cube = grade_mod.bake_cube(g, size=lut_size, strength=strength, title=genre)
    grade_mod.write_cube(sp.lut_path, cube)

    # Overlay plates - the composable assets, as distinct from the stills,
    # which only ever condition the generator.
    plate_frames = []
    for pix in pooled_frames[:3]:
        plate_frames.extend(pix)
    plate_dir = sp.dir / "plates"
    made = plate_mod.mint_plates(plate_frames, plate_dir, noise_sigma=g.noise_sigma)
    print(f"  minted {len(made)} overlay plate(s) -> {plate_dir}")

View on GitHub (pinned to 8321021c54)