roboflow/supervision · error · ValueError
max_axis must be positive when provided
Error message
max_axis must be positive when provided
What it means
Raised by sv.Color.from_rgba_tuple when any of the four (r, g, b, a) values is outside 0-255, including alpha. The method validates the full RGBA quartet before constructing the Color. Alpha here is a byte (0-255), not a 0-1 float, which is the most common source of confusion.
Source
Thrown at src/supervision/key_points/annotators.py:297
"""
def __init__(
self,
sigma: float | Sequence[float] = (1.0, 2.0, 3.0),
color: Color | Sequence[Color] = (Color.GREEN, Color.YELLOW, Color.RED),
max_axis: float | None = None,
) -> None:
sigma_seq: Sequence[float] = (
(sigma,) if isinstance(sigma, (int, float)) else sigma
)
color_seq: Sequence[Color] = (color,) if isinstance(color, Color) else color
if len(sigma_seq) == 0:
raise ValueError("sigma must contain at least one value")
if any(s <= 0 for s in sigma_seq):
raise ValueError("All sigma values must be positive")
if max_axis is not None and max_axis <= 0:
raise ValueError("max_axis must be positive when provided")
if len(color_seq) != len(sigma_seq):
raise ValueError(
f"color length ({len(color_seq)}) must match "
f"sigma length ({len(sigma_seq)})"
)
sorted_indices = sorted(
range(len(sigma_seq)), key=lambda i: sigma_seq[i], reverse=True
)
self.sigma = [sigma_seq[i] for i in sorted_indices]
self.color = [color_seq[i] for i in sorted_indices]
self.max_axis = max_axis
def _get_covariances(self, key_points: KeyPoints) -> npt.NDArray[np.float32]:
covariances = key_points.data.get("covariance")
if covariances is None:
raise ValueError(
"key_points.data must contain 'covariance' with shape (N, K, 2, 2)."View on GitHub (pinned to 7f254d9784)
Solutions
- Convert float/percentage alpha to a byte: alpha_byte = int(round(alpha_float * 255)) (e.g. 0.5 -> 128).
- Clamp all four channels to 0-255 before the call.
- If alpha semantics are unclear, prefer from_hex with the 8-digit #RRGGBBAA form which documents alpha as a byte.
- Double-check you are not passing RGBA where the code expects BGRA.
Example fix
# before sv.Color.from_rgba_tuple((255, 0, 0, 0.5)) # CSS-style float alpha # after sv.Color.from_rgba_tuple((255, 0, 0, int(round(0.5 * 255)))) # alpha = 128
Defensive patterns
Strategy: validation
Validate before calling
def alpha_to_byte(a) -> int:
"""Accept 0-1 float or 0-255 int alpha; return a valid byte alpha."""
a = a * 255 if isinstance(a, float) and a <= 1.0 else a
return max(0, min(255, int(round(a))))
# before: sv.Color.from_rgba_tuple((255, 0, 0, css_alpha))
# after: sv.Color.from_rgba_tuple((255, 0, 0, alpha_to_byte(css_alpha))) Type guard
def is_valid_rgba_tuple(t: tuple) -> bool:
"""True if t is four numbers (r, g, b, a) each within 0-255."""
return len(t) == 4 and all(isinstance(v, (int, float)) and 0 <= v <= 255 for v in t) Prevention
- Never port CSS rgba(..., 0.5) alpha directly — supervision alpha is a 0-255 byte.
- Keep alpha blending math clamped per frame; transparency animations commonly drift past 255 or below 0.
- Prefer the 8-digit hex form (#RRGGBBAA) when alpha comes from string config, since the byte semantics are explicit.
When it happens
Trigger: sv.Color.from_rgba_tuple((255, 0, 0, 1.0)) with a CSS-style alpha float, sv.Color.from_rgba_tuple((255, 0, 0, 300)) from unclamped alpha math, or negative alpha values from blending calculations.
Common situations: Porting CSS rgba(255, 0, 0, 0.5) colors directly (CSS alpha is 0-1); UI frameworks or config files expressing opacity as percentages or floats; gradually varying transparency in overlays without clamping alpha per frame.
Related errors
- color length ({len(color_seq)}) must match sigma length ({le
- Edge indices must use the 1-based convention and be within t
- sigma must contain at least one value
- All sigma values must be positive
- module {__name__} has no attribute {name}
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/144287703a68337e.
Report an issue: GitHub.