affaan-m/ECC · error · SystemExit
stage ' ' failed with exit
Error message
stage '{label}' failed with exit {proc.returncode} What it means
pipeline.py's _run wraps a subprocess stage of the full chain; when the child process exits non-zero it raises SystemExit with a message naming the stage label and exit code. It converts an arbitrary downstream tool failure into a uniform, labeled pipeline abort.
Solutions
- Read the child stage's output printed just above the failure to find the root cause
- Re-run only the failed stage directly to iterate faster and see full stderr
- Fix the underlying stage-specific problem (missing refs, name collision, etc.) before rerunning the pipeline
- Check exit code semantics: nonzero codes like 2 from verify indicate check failures rather than crashes
Example fix
// before python pipeline.py --genre noir --refs ref.mp4 # stage 'mint' failed with exit 1 // after python mint.py noir --refs ref.mp4 # run stage directly to see full error, then rerun pipeline
Defensive patterns
Strategy: try-catch
Try / catch
try:
pipeline.main()
except SystemExit as e:
m = re.search(r"stage '(\w+)' failed with exit (\d+)", str(e))
if m:
stage, code = m.groups()
rerun_stage_directly(stage) # see full stderr there Prevention
- Run each stage standalone first when debugging
- Always read the child stage output above the failure line
- Fix stage-level root causes instead of retrying the whole pipeline
When it happens
Trigger: Any wrapped stage script (mint.py, mint3d.py, forge.py, resolve_ingest.py, verify) exits non-zero - e.g. due to the other errors in this set: unreadable refs, existing outputs, missing stills, invalid names.
Common situations: Chained runs where an early stage fails and the pipeline halts with only 'stage X failed with exit N'; Python's default exit 1 from an uncaught exception in a stage, or exit 2 from a failed verify.
Related errors
- failed
- blender rendered nothing
- classifier subprocess failed
- Codex invocation failed
- Codex probe failed ` : ''}
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/33aa1898e8b3ceed.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/pipeline.py:48
import sys
import time
from pathlib import Path
SCRIPTS = Path(__file__).resolve().parent
def _command(cmd: list[str]) -> list[str]:
"""Resolve tools, while retaining caller-relative media and output paths."""
return [sys.executable, str(SCRIPTS / cmd[0]), *cmd[1:]]
def _run(label: str, cmd: list[str]) -> None:
print(f"\n{'=' * 70}\n[{label}] {' '.join(cmd[:6])} ...\n{'=' * 70}")
t = time.time()
proc = subprocess.run(_command(cmd))
if proc.returncode != 0:
raise SystemExit(f"stage '{label}' failed with exit {proc.returncode}")
print(f"[{label}] done in {time.time() - t:.0f}s")
def main() -> None:
ap = argparse.ArgumentParser(description="Run the full taste-forge chain.")
ap.add_argument("--genre", required=True)
ap.add_argument("--refs", nargs="*", default=None,
help="reference videos; omit to reuse an existing pack")
ap.add_argument("--takes", nargs="+", help="existing local takes; skips every provider stage")
ap.add_argument("--fps", type=float, default=None, help="output frame rate")
ap.add_argument("--brief", default="", help="WHAT HAPPENS in the new piece")
ap.add_argument("--style-steer", default="", help="HOW IT LOOKS, per-run nudge")
ap.add_argument("--duration", type=float, default=12.0,
help="best-effort cadence target in seconds, not an exact duration; actual result is reported")
ap.add_argument("--base-video", default=None, help="existing footage to supplement")
ap.add_argument("--base-ratio", type=float, default=0.35)
ap.add_argument("--out", default=None)
ap.add_argument("--root", default="stylepacks")View on GitHub (pinned to 8321021c54)