cocoindex-io/cocoindex · error · ValueError
Unsupported type for TypeChecker: {tp}
Error message
Unsupported type for TypeChecker: {tp} What it means
_build_check_fn raises this ValueError when TypeChecker is constructed with a type annotation the runtime checker builder does not know how to validate. The builder walks typing constructs (Optional, list, dict, tuple, bare classes); any annotation that falls through all branches — e.g. union of 3+ types, Literal, TypedDict, dataclass, generics like Sequence[T], callables — is rejected at TypeChecker construction time, not at check time. It is an upfront capability error: the checker cannot be built, so no value is ever validated.
Source
Thrown at python/cocoindex/_internal/datatype.py:393
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
# Simple concrete type: str, int, bytes, uuid.UUID, etc.
if isinstance(tp, type):
def check_isinstance(value: Any, path: str) -> None:
if not isinstance(value, tp):
loc = f" at {path}" if path else ""
raise TypeError(
f"expected {tp.__name__}{loc}, got {type(value).__name__}: {value!r}"
)
return check_isinstance
raise ValueError(f"Unsupported type for TypeChecker: {tp}")
T = TypeVar("T")
class TypeChecker(Generic[T]):
"""
Pre-built runtime type checker.
Analyzes a type annotation once at construction time and builds optimized
validation closures. At check time, validation is a fast series of
``isinstance`` calls and tuple-length comparisons — no reflection.
Usage::
_TABLE_KEY_CHECKER: TypeChecker[tuple[str, str]] = TypeChecker(tuple[str, str])
# In reconcile():View on GitHub (pinned to e84aa99b32)
Solutions
- Replace the annotation with one of the supported forms: a plain class (str, int, bytes, uuid.UUID), Optional[X], list[X], dict[K, V], tuple[X, ...] or tuple[X, Y], or a union of at most Optional + one type.
- If richer validation is needed, write a small custom isinstance-based check function instead of using TypeChecker.
- Narrow the declared type at the boundary: accept the broad annotation in the signature but convert/coerce to the concrete supported type before constructing TypeChecker.
- Check datatype.py for the exact supported grammar and add a branch in _build_check_fn if this is an internal type you own.
Example fix
// before _KEY_CHECKER = TypeChecker(dict[str, str | int]) # ValueError: unsupported // after _KEY_CHECKER = TypeChecker(dict[str, str]) # supported concrete form
Defensive patterns
Strategy: type-guard
Validate before calling
import typing
SUPPORTED = (str, int, float, bool, bytes, type(None))
def _is_supported(tp) -> bool:
if tp in SUPPORTED or isinstance(tp, type):
return True
origin = typing.get_origin(tp)
if origin is typing.Union:
args = typing.get_args(tp)
return len(args) == 2 and type(None) in args
return origin in (list, dict, tuple, set)
# call before construction: assert _is_supported(tp), tp Type guard
def is_typechecker_supported(tp: object) -> bool:
"""True if _build_check_fn can handle this annotation."""
import typing
origin = typing.get_origin(tp)
if origin is None:
return isinstance(tp, type)
if origin is typing.Union:
args = typing.get_args(tp)
return len(args) == 2 and type(None) in args
return origin in (list, dict, tuple) Try / catch
try:
checker = TypeChecker(tp)
except ValueError as e:
raise TypeError(f"annotation {tp!r} not runtime-checkable by TypeChecker") from e Prevention
- Keep TypeChecker annotations to plain classes, Optional[X], list/dict/tuple forms
- Never feed Literal, Callable, Protocols, TypedDict, or 3+-way unions into TypeChecker
- Test type-checker construction at import time so unsupported annotations fail in CI, not at runtime
- Prefer converting rich annotations to concrete types at boundaries before validation
When it happens
Trigger: Calling TypeChecker(tp) (or _build_check_fn directly) with an unsupported annotation such as Literal['a','b'], Callable[[int], str], Sequence[int], a 3+-member union (int | str | None), TypedDict, dataclass types, or generic aliases not specially handled by the builder.
Common situations: Developers annotating internal function arguments or target-state keys with rich typing-library constructs and expecting TypeChecker to validate them; upgrading code that previously used simple types (str, tuple[str, str]) to fancier annotations; refactoring a shared type alias into a union or Protocol and passing it to TypeChecker.
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
- record_type must be a record type (dataclass, NamedTuple, Py
- use_mount() requires a ComponentSubpath when the function ha
- LiveComponent classes cannot be used with use_mount(). Use m
- mount() requires a ComponentSubpath when the function has no
- mount_each() requires a ComponentSubpath when the function h
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/89be281519d3207d.
Report an issue: GitHub.