ultralytics/yolov5 · error · NotImplementedError

--task not in ("train", "val", "test", "speed", "study")

Error message

--task {opt.task} not in ("train", "val", "test", "speed", "study")

What it means

Raised at the bottom of val.py's main() when opt.task is not one of the five supported validation tasks: 'train', 'val', 'test', 'speed', 'study'. main() dispatches via if/elif on opt.task; any other string falls through to NotImplementedError. 'speed' benchmarks inference speed and 'study' sweeps image sizes across weights, so only those five strings are meaningful here.

Solutions

  1. Use one of the five allowed values: --task val (default), --task train, --task test, --task speed, or --task study.
  2. If you meant detection inference, use detect.py instead of val.py --task detect.
  3. Audit wrapper scripts/evolution configs that set opt.task programmatically and clamp the value to the allowed set.

Example fix

# before
python val.py --task detect --weights yolov5s.pt
# after
python detect.py --weights yolov5s.pt --source data/images
# or, for metrics on the val split
python val.py --task val --weights yolov5s.pt --data coco.yaml
Defensive patterns

Strategy: validation

Validate before calling

VAL_TASKS = ("train", "val", "test", "speed", "study")
assert opt.task in VAL_TASKS, f"--task must be one of {VAL_TASKS}; for inference use detect.py, not val.py"

Type guard

def is_valid_val_task(task: str) -> bool:
    """val.py supports exactly these task values, case-sensitive."""
    return isinstance(task, str) and task in {"train", "val", "test", "speed", "study"}

Try / catch

try:
    main(opt)
except NotImplementedError as e:
    if "not in" in str(e):
        print(f"Unsupported --task {opt.task!r}; valid: train, val, test, speed, study. Use detect.py for inference.")
    else:
        raise

Prevention

When it happens

Trigger: Running python val.py --task <anything-else>, e.g. --task detect, --task trainval, --task Validation (case-sensitive), --task inference, or omitting the default via a script that sets opt.task programmatically to an invalid value.

Common situations: Confusing val.py's task vocabulary with train.py or detect.py (people try --task detect or --task predict); casing/typo errors; hyperparameter evolution or wrapper scripts that inject an unsupported task string; older YOLO versions with different task lists.

Related errors


AI-assisted analysis of ultralytics/yolov5@20d1d78a08 (2026-08-15). Data as JSON: /api/errors/09de5b62f3cd5441. Report an issue: GitHub.

Appendix: source

Thrown at val.py:523

            # python val.py --task speed --data coco.yaml --batch 1 --weights yolov5n.pt yolov5s.pt...
            opt.conf_thres, opt.iou_thres, opt.save_json = 0.25, 0.45, False
            for opt.weights in weights:
                run(**vars(opt), plots=False)

        elif opt.task == "study":  # speed vs mAP benchmarks
            # python val.py --task study --data coco.yaml --iou 0.7 --weights yolov5n.pt yolov5s.pt...
            for opt.weights in weights:
                f = f"study_{Path(opt.data).stem}_{Path(opt.weights).stem}.txt"  # filename to save to
                x, y = list(range(256, 1536 + 128, 128)), []  # x axis (image sizes), y axis
                for opt.imgsz in x:  # img-size
                    LOGGER.info(f"\nRunning {f} --imgsz {opt.imgsz}...")
                    r, _, t = run(**vars(opt), plots=False)
                    y.append(r + t)  # results and times
                np.savetxt(f, y, fmt="%10.4g")  # save
            subprocess.run(["zip", "-r", "study.zip", *glob.glob("study_*.txt")], check=False)
            plot_val_study(x=x)  # plot
        else:
            raise NotImplementedError(f'--task {opt.task} not in ("train", "val", "test", "speed", "study")')


if __name__ == "__main__":
    opt = parse_opt()
    main(opt)

View on GitHub (pinned to 20d1d78a08)