cocoindex-io/cocoindex · error · TypeError

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

Error message

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

What it means

For a tuple[X, ...] (variable-length, Any element) annotation, TypeChecker emits check_var_tuple_any, which only verifies the value is a tuple instance. Any non-tuple (list, generator, numpy array) raises TypeError with an optional `at <path>` suffix.

Source

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

                except TypeError:
                    continue
            loc = f" at {path}" if path else ""
            raise TypeError(
                f"expected {tp}{loc}, got {type(value).__name__}: {value!r}"
            )

        return check_union

    # Tuple types
    if origin is tuple:
        if len(args) == 2 and args[1] is Ellipsis:
            # Variable-length: tuple[X, ...]
            if args[0] is Any:

                def check_var_tuple_any(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_var_tuple_any

            elem_fn = _build_check_fn(args[0])

            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, ...]

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Wrap the value in tuple(...) before passing it
  2. Change the annotation to Sequence[X] or list[X] if order matters but tuple semantics don't
  3. Materialize generators/arrays into a tuple at construction of the key

Example fix

// before
key = ["a", "b"]  # annotated tuple[str, ...]

// after
key = ("a", "b")
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

def is_tuple(v: object) -> TypeGuard[tuple]:
    return isinstance(v, tuple)

Try / catch

try:
    checker.check(key)
except TypeError as e:
    if "expected tuple" in str(e):
        key = tuple(key)
    else:
        raise

Prevention

When it happens

Trigger: Passing a list, generator, or ndarray where a tuple[X, ...]-annotated value is validated by TypeChecker (e.g. stable memo keys, table keys built from tuples).

Common situations: Building keys from list(...) instead of tuple(...); passing a numpy array or itertools result where a tuple was declared; JSON round-trips turning tuples into lists.

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/28ac77d0e4083c8d. Report an issue: GitHub.