roboflow/supervision · error · ValueError
Only RETR_TREE is supported by the fallback
Error message
Only RETR_TREE is supported by the fallback
What it means
The fallback `findContours` in src/supervision/_cv2/_contours.py:145 implements only the retrieval mode supervision itself uses (`RETR_TREE`); it maps every other mode constant onto that check and raises for anything else. Without OpenCV, modes like RETR_EXTERNAL, RETR_LIST, or RETR_CCOMP are not emulated because they imply different contour sets/relationships.
Source
Thrown at src/supervision/_cv2/_contours.py:145
for index, point in enumerate(contour):
previous = point - contour[index - 1]
following = contour[(index + 1) % len(contour)] - point
if (
np.any(previous)
and np.any(following)
and np.array_equal(np.sign(previous), np.sign(following))
):
continue
keep.append(point)
return np.asarray(keep, dtype=np.int32)
def _find_contours(
image: npt.NDArray[Any], mode: int, method: int
) -> tuple[list[npt.NDArray[np.int32]], npt.NDArray[np.int32] | None]:
"""Find contours for the supported tree and SIMPLE modes."""
if mode != _RETR_TREE:
raise ValueError("Only RETR_TREE is supported by the fallback")
if method != _CHAIN_APPROX_SIMPLE:
raise ValueError("Only CHAIN_APPROX_SIMPLE is supported by the fallback")
values = np.asarray(image)
if values.ndim != 2:
raise ValueError("Contour input must be a two-dimensional image")
traced = [_compress_contour(contour) for contour in _trace_borders(values != 0)]
if not traced:
return [], None
return [contour.reshape(-1, 1, 2) for contour in traced], None
View on GitHub (pinned to 7f254d9784)
Solutions
- Use `mode=cv2.RETR_TREE` and filter contours yourself (e.g. drop contours that are holes by checking parents in hierarchy or by area)
- Install `opencv-python` if the retrieval mode semantics matter for your pipeline
- Pre-filter the mask (e.g. fill holes) so RETR_TREE results match what RETR_EXTERNAL would have returned
Example fix
// before contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) // after contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) outer = [c for c in contours if cv2.contourArea(c) >= min_area] # approximate filtering
Defensive patterns
Strategy: fallback
Validate before calling
from supervision._cv2 import BACKEND_NAME # 'opencv' or 'fallback'
SUPPORTED_RETRIEVAL = {"RETR_TREE"}
def assert_retrieval_supported(mode_name: str) -> None:
"""Fail fast when a contour retrieval mode is unavailable on the fallback."""
if BACKEND_NAME != "opencv" and mode_name not in SUPPORTED_RETRIEVAL:
raise ValueError(f"contour mode {mode_name} needs opencv-python installed") Prevention
- Standardize contour extraction on RETR_TREE + CHAIN_APPROX_SIMPLE for portable code
- Add opencv-python to deployment dependencies if you use other retrieval modes
When it happens
Trigger: Calling `cv2.findContours` with `mode=cv2.RETR_EXTERNAL` (the most common alternative) while running on the fallback backend; also any typo'd or custom mode integer.
Common situations: Code written against real OpenCV using RETR_EXTERNAL to get only outer contours, then run in a slim container without opencv-python; mixing cv2 constant values copied from a different OpenCV version.
Related errors
- Only None hierarchy is supported by the fallback
- Only CHAIN_APPROX_SIMPLE is supported by the fallback
- Contour input must be a two-dimensional image
- Contour border tracing did not converge
- Drawing points must have shape (N, 2) or (N, 1, 2)
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/b2e2054dd3c79a3d.
Report an issue: GitHub.