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
- Use one of the five allowed values: --task val (default), --task train, --task test, --task speed, or --task study.
- If you meant detection inference, use detect.py instead of val.py --task detect.
- 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
- Remember the task vocabularies: val.py takes train/val/test/speed/study; detection inference lives in detect.py.
- Copy CLI flags from val.py's parse_opt help text rather than from other scripts.
- In wrapper scripts, validate task strings against the allowed set before invoking val.py.
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.