cocoindex-io/cocoindex · error · TypeError
expected None{loc}, got {type(value).__name__}
Error message
expected None{loc}, got {type(value).__name__} What it means
TypeChecker builds a validator per type annotation. For the NoneType annotation (type(None) / None in a Union), the generated check_none closure raises TypeError when the value is not None, with an optional `at <path>` location suffix. This enforces that a None-typed slot only ever holds None.
Source
Thrown at python/cocoindex/_internal/datatype.py:301
def _build_check_fn(tp: Any) -> _CheckFn:
"""
Build a validation closure for the given type annotation.
Returns a function ``(value, path) -> None`` that raises ``TypeError``
on mismatch. *path* carries positional context for error messages
(empty string at top level, ``"[0]"`` for tuple element 0, etc.).
"""
origin = typing.get_origin(tp)
args = typing.get_args(tp)
# NoneType
if tp is type(None):
def check_none(value: Any, path: str) -> None:
if value is not None:
loc = f" at {path}" if path else ""
raise TypeError(f"expected None{loc}, got {type(value).__name__}")
return check_none
# Any — accept everything
if tp is Any:
return lambda _v, _p: None
# Union: str | int, str | None, etc.
if origin in (types.UnionType, typing.Union):
sub_fns = [_build_check_fn(a) for a in args]
def check_union(value: Any, path: str) -> None:
for fn in sub_fns:
try:
fn(value, path)
return
except TypeError:
continueView on GitHub (pinned to e84aa99b32)
Solutions
- Fix the annotation to the actual intended type instead of None
- Make the value actually None at the call site
- If both None and a real type are valid, annotate as `T | None`
Example fix
// before
def cb() -> None:
return result # returns a value
// after
def cb() -> Result:
return result
# or return None if the declared type is correct Defensive patterns
Strategy: type-guard
Validate before calling
if value is not None:
raise TypeError("slot annotated None received a non-None value") Type guard
def is_none(v: object) -> TypeGuard[None]:
return v is None Try / catch
try:
checker.check(value)
except TypeError as e:
if "expected None" in str(e):
value = None
else:
raise Prevention
- Don't use bare `None` as an annotation placeholder; use Optional[T] or the real type
- Ensure functions declared -> None don't return values
- Validate return values in tests for None-typed memo results
When it happens
Trigger: A value typed as None (or the None member of a union being checked individually by check_union) receives a non-None value at runtime — e.g. a memoized function declared to return None actually returns something, or a tuple element typed None gets a real value.
Common situations: Accidentally annotating a field with `None` instead of the intended type; returning a sentinel value from a function declared -> None; misuse of None as a placeholder type.
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
- expected {tp}{loc}, got {type(value).__name__}: {value!r}
- expected tuple{loc}, got {type(value).__name__}
- Context key '{key}': expected {t.__name__}, got {type(value)
- Invalid dtype specification: {dtype_spec}
- NDArray for Vector must use a concrete numpy dtype, got `Any
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/4c94edf64ebac497.
Report an issue: GitHub.