{"record":{"id":"8b85b0a5ac777ea9","repo":"roboflow/supervision","slug":"the-magnitude-of-the-vector-cannot-be-zero","errorCode":null,"errorMessage":"The magnitude of the vector cannot be zero.","messagePattern":"The magnitude of the vector cannot be zero\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/detection/line_zone.py","lineNumber":239,"sourceCode":"\n    def _evict_stale_crossing_history(self, current_keys: set[int]) -> None:\n        for key in list(self.crossing_state_history):\n            if key in current_keys:\n                self._tracker_frames_absent.pop(key, None)\n            else:\n                absent = self._tracker_frames_absent.get(key, 0) + 1\n                if absent >= self.crossing_history_length:\n                    del self.crossing_state_history[key]\n                    self._tracker_frames_absent.pop(key, None)\n                else:\n                    self._tracker_frames_absent[key] = absent\n\n    @staticmethod\n    def _calculate_region_of_interest_limits(vector: Vector) -> tuple[Vector, Vector]:\n        magnitude = vector.magnitude\n\n        if magnitude == 0:\n            raise ValueError(\"The magnitude of the vector cannot be zero.\")\n\n        delta_x = vector.end.x - vector.start.x\n        delta_y = vector.end.y - vector.start.y\n\n        unit_vector_x = delta_x / magnitude\n        unit_vector_y = delta_y / magnitude\n\n        perpendicular_vector_x = -unit_vector_y\n        perpendicular_vector_y = unit_vector_x\n\n        start_region_limit = Vector(\n            start=vector.start,\n            end=Point(\n                x=vector.start.x + perpendicular_vector_x,\n                y=vector.start.y + perpendicular_vector_y,\n            ),\n        )\n        end_region_limit = Vector(","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/detection/line_zone.py#L221-L257","documentation":"LineZone's internal _calculate_region_of_interest_limits computes a unit vector and its perpendicular from the zone's direction vector; a zero-magnitude vector (start point equals end point) makes the division undefined, so a ValueError is raised. A degenerate line has no direction to cross, so the geometry cannot be built.","triggerScenarios":"sv.LineZone(start=Point(x=100, y=200), end=Point(x=100, y=200)) — identical start and end; or a line built from computed points (e.g. percentage offsets of frame size) that collapse to the same coordinate due to rounding or a zero-size frame.","commonSituations":"Generating line endpoints from percentages of a frame that failed to load (width=height=0); rounding both endpoints to the same pixel; dynamically drawn zones where the user clicked the same point twice.","solutions":["Ensure start and end differ in at least one coordinate before constructing LineZone.","Check the source frame dimensions when endpoints are computed as fractions of frame size.","When zones are user-drawn, reject clicks where start == end and prompt again."],"exampleFix":"# before\n zone = sv.LineZone(\n     start=sv.Point(x=cx, y=cy), end=sv.Point(x=cx, y=cy)\n )\n\n# after\n if start == end:\n     raise ValueError(\"LineZone start and end must differ\")\n zone = sv.LineZone(start=start, end=end)","handlingStrategy":"validation","validationCode":"if start.x == end.x and start.y == end.y:\n    raise ValueError(\"LineZone start and end must not be the same point\")\nzone = sv.LineZone(start=start, end=end)","typeGuard":"def is_degenerate_line(start: sv.Point, end: sv.Point) -> bool:\n    return start.x == end.x and start.y == end.y","tryCatchPattern":null,"preventionTips":["Validate endpoints when zones are defined in config or drawn by users.","Check frame dimensions before deriving endpoints from percentages.","Add a startup assert over all configured zones."],"tags":["line-zone","geometry","validation"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}