{"record":{"id":"c27423b6c65940b6","repo":"roboflow/supervision","slug":"only-class-instances-are-supported-not-classes","errorCode":null,"errorMessage":"Only class instances are supported, not classes.","messagePattern":"Only class instances are supported, not classes\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/utils/internal.py","lineNumber":193,"sourceCode":"        instance: The instance of a class\n        include_properties: Whether to include properties in the result\n\n    Usage:\n        ```pycon\n        >>> from supervision.utils.internal import get_instance_variables\n        >>> import numpy as np\n        >>> from supervision import Detections\n        >>> detections = Detections(xyxy=np.array([[1, 2, 3, 4]]))\n        >>> variables = get_instance_variables(detections)\n        >>> 'xyxy' in variables\n        True\n        >>> 'data' in variables\n        True\n\n        ```\n    \"\"\"\n    if isinstance(instance, type):\n        raise ValueError(\"Only class instances are supported, not classes.\")\n\n    fields = {\n        name\n        for name, val in inspect.getmembers(instance)\n        if not callable(val) and not name.startswith(\"_\")\n    }\n\n    if not include_properties:\n        properties = {\n            name\n            for name, val in inspect.getmembers(instance.__class__)\n            if isinstance(val, property)\n        }\n        fields -= properties\n\n    return fields\n","sourceCodeStart":175,"sourceCodeEnd":210,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/utils/internal.py#L175-L210","documentation":"Raised by get_instance_variables() in supervision.utils.internal when the `instance` argument is a class object (e.g. Detections) rather than an instance (e.g. Detections(xyxy=...)). The helper inspects public attributes via inspect.getmembers, which behaves very differently on classes, so it explicitly rejects them to avoid misleading results.","triggerScenarios":"Calling get_instance_variables(Detections) or get_instance_variables(sv.BoxAnnotator) instead of get_instance_variables(detections) / get_instance_variables(box_annotator).","commonSituations":"Writing generic serialization or introspection tooling over supervision objects and forgetting to instantiate; passing a factory or class reference through a variable named `instance`; copy-paste from doctests that show the class name.","solutions":["Pass an instance: get_instance_variables(Detections(xyxy=np.array([[1,2,3,4]]))).","If you have the class, construct a minimal valid instance first.","Audit call sites where the value may be either a class or an instance and branch on isinstance(x, type)."],"exampleFix":"// before\nvars = get_instance_variables(sv.Detections)  # ValueError\n\n// after\ndetections = sv.Detections(xyxy=np.array([[1, 2, 3, 4]]))\nvars = get_instance_variables(detections)","handlingStrategy":"validation","validationCode":"if isinstance(obj, type):\n    raise ValueError(f'Expected an instance, got class {obj.__name__}')\nvariables = get_instance_variables(obj)","typeGuard":"def is_instance_not_class(obj: object) -> bool:\n    return not isinstance(obj, type)","tryCatchPattern":"try:\n    get_instance_variables(target)\nexcept ValueError as e:\n    if 'class instances' in str(e):\n        target = target()  # instantiate with defaults if possible\n    raise","preventionTips":["Name variables honestly (instance vs cls) in introspection code.","Add isinstance(x, type) checks in generic tooling that accepts either."],"tags":["introspection","validation","api-misuse"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}