ultralytics/yolov5 · error · NotImplementedError

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

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.

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)

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.