{"record":{"id":"b5aac7fc189278d8","repo":"cocoindex-io/cocoindex","slug":"expected-tp-loc-got-type-value-name","errorCode":null,"errorMessage":"expected {tp}{loc}, got {type(value).__name__}","messagePattern":"expected (.+?)(.+?), got (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/_internal/datatype.py","lineNumber":361,"sourceCode":"\n            def check_var_tuple(value: Any, path: str) -> None:\n                if not isinstance(value, tuple):\n                    loc = f\" at {path}\" if path else \"\"\n                    raise TypeError(f\"expected tuple{loc}, got {type(value).__name__}\")\n                for i, elem in enumerate(value):\n                    elem_fn(elem, f\"{path}[{i}]\")\n\n            return check_var_tuple\n\n        if args:\n            # Fixed-length: tuple[X, Y, ...]\n            elem_fns = [_build_check_fn(a) for a in args]\n            expected_len = len(args)\n\n            def check_fixed_tuple(value: Any, path: str) -> None:\n                if not isinstance(value, tuple):\n                    loc = f\" at {path}\" if path else \"\"\n                    raise TypeError(f\"expected {tp}{loc}, got {type(value).__name__}\")\n                if len(value) != expected_len:\n                    loc = f\" at {path}\" if path else \"\"\n                    raise TypeError(\n                        f\"expected tuple of length {expected_len}{loc}, \"\n                        f\"got length {len(value)}\"\n                    )\n                for i, (elem, fn) in enumerate(zip(value, elem_fns)):\n                    fn(elem, f\"{path}[{i}]\")\n\n            return check_fixed_tuple\n\n        # Bare tuple (no args) — just check isinstance\n        def check_bare_tuple(value: Any, path: str) -> None:\n            if not isinstance(value, tuple):\n                loc = f\" at {path}\" if path else \"\"\n                raise TypeError(f\"expected tuple{loc}, got {type(value).__name__}\")\n\n        return check_bare_tuple","sourceCodeStart":343,"sourceCodeEnd":379,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/_internal/datatype.py#L343-L379","documentation":"For a fixed-length tuple type like tuple[int, str], the TypeChecker builds check_fixed_tuple, which first requires the value to be an actual tuple. If it is not (a list, for example), this TypeError is raised before the length check. The library requires exact tuple instances so element-by-element validation against the declared arity is meaningful.","triggerScenarios":"Passing a list or other sequence where a fixed-arity tuple type tuple[A, B, ...] is declared — e.g. a @coco.fn parameter, a declared target-state row field, or any TypeChecker.check() call.","commonSituations":"Writing point = [1.0, 2.0] but declaring tuple[float, float]; JSON-decoded data (always lists) fed into tuple-typed fields; dict values or tuple-like namedtuples passed directly.","solutions":["Convert to a tuple at the call site: tuple(my_list)","If the data is naturally a list, change the declared type to a list type","For JSON-decoded data, wrap in tuple(...) right after parsing"],"exampleFix":"// before\npoint = [1.0, 2.0]\ncheck(point)  # declared tuple[float, float]\n// after\npoint = (1.0, 2.0)\ncheck(point)","handlingStrategy":"type-guard","validationCode":"if not isinstance(value, tuple):\n    value = tuple(value)","typeGuard":"def is_fixed_tuple(value: object, n: int) -> TypeGuard[tuple]:\n    return isinstance(value, tuple) and len(value) == n","tryCatchPattern":"try:\n    check(value)\nexcept TypeError as e:\n    if \"expected tuple\" in str(e):\n        raise ValueError(f\"need a tuple, got {type(value).__name__}; wrap with tuple(...)\") from e","preventionTips":["Use tuple literals (a, b) not lists [a, b] for tuple-typed fields","Remember JSON/YAML decoding yields lists — convert after parsing","Use NamedTuple or a dataclass instead of positional fixed tuples for readability"],"tags":["python","type-checking","tuple","validation"],"backgroundTag":"type-mismatch","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}