cocoindex-io/cocoindex · error · TypeError
memo_key transform for *args must return tuple, got {type(va
Error message
memo_key transform for *args must return tuple, got {type(varargs).__name__} What it means
memo_key specifications can supply a transform (varargs_override) applied to a function's *args tuple before fingerprinting. The transform must return a tuple; any other return type raises TypeError because the result is concatenated into the final memo-key args.
Source
Thrown at python/cocoindex/_internal/function.py:481
for i, arg in enumerate(fixed_args):
key_fn = memo_key_plan.positional_specs[i]
if is_not_set(key_fn):
new_fixed_args.append(arg)
elif key_fn is None:
continue # Exclude this positional arg
else:
new_fixed_args.append(key_fn(arg))
# Apply varargs override if present (whole *args parameter)
if not is_not_set(memo_key_plan.varargs_override):
if memo_key_plan.varargs_override is None:
# Exclude entire *args
varargs = ()
else:
# Transform entire *args tuple
varargs = memo_key_plan.varargs_override(varargs)
if not isinstance(varargs, tuple):
raise TypeError(
f"memo_key transform for *args must return tuple, "
f"got {type(varargs).__name__}"
)
# Combine fixed args and varargs
final_args = tuple(new_fixed_args) + varargs
# Process kwargs: separate matched (keyword-only/POSITIONAL_OR_KEYWORD passed as kwarg)
# from unmatched (extra **kwargs)
new_kwargs: dict[str, Any] = {}
unmatched_kwargs: dict[str, Any] = {}
for key, value in kwargs.items():
if key in memo_key_plan.keyword_specs:
key_fn = memo_key_plan.keyword_specs[key]
if key_fn is None:
continue # Exclude this kwarg
new_kwargs[key] = key_fn(value)View on GitHub (pinned to e84aa99b32)
Solutions
- Return a tuple from the varargs transform: tuple(transformed)
- Wrap single values: (value,)
- Materialize generators/lists into a tuple before returning
Example fix
# before
def key(*args):
return [normalize(a) for a in args]
# after
def key(*args):
return tuple(normalize(a) for a in args) Defensive patterns
Strategy: validation
Validate before calling
def as_tuple(result):
if not isinstance(result, tuple):
raise TypeError("varargs transform must return tuple")
return result Type guard
def is_tuple(x: object) -> TypeGuard[tuple]:
return isinstance(x, tuple) Prevention
- Always wrap transform output in tuple(...)
- Unit-test memo_key transforms directly (return types are enforced lazily at call time)
- Add return type annotations: def t(*args) -> tuple: ...
When it happens
Trigger: @coco.fn(memo_key={"*": transform}) (or MemoKeySpec with varargs override) where transform returns a list, generator, or single value instead of a tuple, for a function accepting *args.
Common situations: Writing `return [x for x in args]` in a transform; forgetting to wrap a single normalized value in a tuple; converting args to a string for logging and returning it.
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
- memo_key transform for **kwargs must return dict, got {type(
- Unknown memo_key parameter(s) for {qualified_name(fn)}(): {'
- Unknown memo_key parameter(s) for {qualified_name(fn)}(): {u
- deps= requires logic_tracking to be enabled; with logic_trac
- {type(obj).__name__} cannot be used as a memoization key. Th
AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08).
Data as JSON: /api/errors/65df8370f52aaf15.
Report an issue: GitHub.