cocoindex-io/cocoindex · error · TypeError

expected {tp}{loc}, got {type(value).__name__}

Error message

expected {tp}{loc}, got {type(value).__name__}

What it means

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.

Source

Thrown at python/cocoindex/_internal/datatype.py:361

            def check_var_tuple(value: Any, path: str) -> None:
                if not isinstance(value, tuple):
                    loc = f" at {path}" if path else ""
                    raise TypeError(f"expected tuple{loc}, got {type(value).__name__}")
                for i, elem in enumerate(value):
                    elem_fn(elem, f"{path}[{i}]")

            return check_var_tuple

        if args:
            # Fixed-length: tuple[X, Y, ...]
            elem_fns = [_build_check_fn(a) for a in args]
            expected_len = len(args)

            def check_fixed_tuple(value: Any, path: str) -> None:
                if not isinstance(value, tuple):
                    loc = f" at {path}" if path else ""
                    raise TypeError(f"expected {tp}{loc}, got {type(value).__name__}")
                if len(value) != expected_len:
                    loc = f" at {path}" if path else ""
                    raise TypeError(
                        f"expected tuple of length {expected_len}{loc}, "
                        f"got length {len(value)}"
                    )
                for i, (elem, fn) in enumerate(zip(value, elem_fns)):
                    fn(elem, f"{path}[{i}]")

            return check_fixed_tuple

        # Bare tuple (no args) — just check isinstance
        def check_bare_tuple(value: Any, path: str) -> None:
            if not isinstance(value, tuple):
                loc = f" at {path}" if path else ""
                raise TypeError(f"expected tuple{loc}, got {type(value).__name__}")

        return check_bare_tuple

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Convert to a tuple at the call site: tuple(my_list)
  2. If the data is naturally a list, change the declared type to a list type
  3. For JSON-decoded data, wrap in tuple(...) right after parsing

Example fix

// before
point = [1.0, 2.0]
check(point)  # declared tuple[float, float]
// after
point = (1.0, 2.0)
check(point)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(value, tuple):
    value = tuple(value)

Type guard

def is_fixed_tuple(value: object, n: int) -> TypeGuard[tuple]:
    return isinstance(value, tuple) and len(value) == n

Try / catch

try:
    check(value)
except TypeError as e:
    if "expected tuple" in str(e):
        raise ValueError(f"need a tuple, got {type(value).__name__}; wrap with tuple(...)") from e

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/b5aac7fc189278d8. Report an issue: GitHub.