{"record":{"id":"6f76c3a4c038e2b3","repo":"roboflow/supervision","slug":"number-of-colors-len-colors-must-match-number","errorCode":null,"errorMessage":"Number of colors ({len(colors)}) must match number of key points ({points_count}).","messagePattern":"Number of colors \\((.+?)\\) must match number of key points \\((.+?)\\)\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/key_points/annotators.py","lineNumber":989,"sourceCode":"        else:\n            resolved = labels\n\n        if len(resolved) != points_count:\n            raise ValueError(\n                f\"Number of labels ({len(resolved)}) must match \"\n                f\"number of key points ({points_count}).\"\n            )\n        return resolved\n\n    @staticmethod\n    def _resolve_color_list(\n        colors: Color | list[Color],\n        points_count: int,\n    ) -> list[Color]:\n        \"\"\"Return a per-keypoint color list for a single instance.\"\"\"\n        if isinstance(colors, list):\n            if len(colors) != points_count:\n                raise ValueError(\n                    f\"Number of colors ({len(colors)}) must match \"\n                    f\"number of key points ({points_count}).\"\n                )\n            return colors\n        return [colors] * points_count\n","sourceCodeStart":971,"sourceCodeEnd":995,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/key_points/annotators.py#L971-L995","documentation":"Raised by verify_clean_wheel.py's _wheel_metadata when opening a wheel archive does not yield exactly one path ending in '/METADATA'. A valid wheel contains precisely one *.dist-info/METADATA file; zero means the wheel is malformed or the file is misplaced/misnamed, and more than one means duplicate dist-info directories got packed in. The script refuses to guess which metadata to validate.","triggerScenarios":"Passing a path that is not a real wheel (a zip renamed .whl, or an sdist); a custom build step that writes METADATA at a non-standard path (no '<pkg>.dist-info/' prefix, so endswith('/METADATA') misses it); a packaging bug or manual re-zip producing two dist-info directories; a corrupted download producing a truncated archive read as having no metadata.","commonSituations":"CI downloading wheels from an artifact store that mangles names or contents; developers hand-editing/re-zipping wheels to patch metadata; broken custom build backends (setuptools plugin, bazel rules) emitting non-compliant wheel layouts; pointing the verifier at the dist/ directory glob that matches a stale wheel plus a new one and reading the wrong file.","solutions":["Inspect the archive: unzip -l yourwheel.whl | grep METADATA and confirm there is exactly one <name>.dist-info/METADATA entry.","If zero entries: rebuild the wheel with a standard backend (python -m build --wheel) from a clean checkout instead of custom zipping.","If multiple entries: delete stale dist-info directories from the build dir and rebuild; never merge two wheels' contents.","Verify you are passing an actual built wheel (fresh artifact), not a renamed zip or sdist, to verify_clean_wheel.py."],"exampleFix":"# before: hand-zipped 'wheel' with misplaced metadata\nzip -r custom.whl mypackage/ METADATA  # METADATA at archive root -> 0 matches\n\n# after: build a compliant wheel\n# python -m build --wheel\n# dist/supervision-*.whl now contains supervision-x.y.z.dist-info/METADATA","handlingStrategy":"validation","validationCode":"import zipfile, pathlib\n\ndef is_clean_wheel(wheel: pathlib.Path) -> bool:\n    \"\"\"True if the archive has exactly one */METADATA entry (valid wheel layout).\"\"\"\n    if not wheel.name.endswith('.whl'):\n        return False\n    with zipfile.ZipFile(wheel) as z:\n        return len([n for n in z.namelist() if n.endswith('/METADATA')]) == 1","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build wheels with a standard backend (python -m build --wheel); never hand-zip or merge archives.","In CI, verify the artifact is a fresh wheel from this build (name includes version and tag) before running verification.","Run unzip -l on the wheel when this fails to see whether METADATA is missing, misplaced, or duplicated."],"tags":["ci","packaging","wheel","metadata","malformed","valueerror"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}