cocoindex-io/cocoindex · error · TypeError
memo_key transform for **kwargs must return dict, got {type(
Error message
memo_key transform for **kwargs must return dict, got {type(transformed).__name__} What it means
A bug guard in the memo-key machinery, not user input validation: when a @coco.fn(memo=True) function has a varkw_override for **kwargs, _apply_memo_key applies that transform to the collected unmatched keyword arguments and expects it to yield a dict (the fingerprintable key material for the whole kwargs bag). A transform returning anything else would silently produce an unusable memo key, so this TypeError fires to surface a malformed user-supplied transform function at call time. Fix the varkw_override transform so it returns a dict.
Source
Thrown at python/cocoindex/_internal/function.py:512
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)
else:
unmatched_kwargs[key] = value
# Apply varkw override if present (whole **kwargs parameter)
if not is_not_set(memo_key_plan.varkw_override):
if memo_key_plan.varkw_override is None:
# Exclude entire **kwargs
unmatched_kwargs = {}
else:
# Transform entire unmatched kwargs dict
transformed = memo_key_plan.varkw_override(unmatched_kwargs)
if not isinstance(transformed, dict):
raise TypeError(
f"memo_key transform for **kwargs must return dict, "
f"got {type(transformed).__name__}"
)
unmatched_kwargs = transformed
# Merge matched and unmatched kwargs
new_kwargs.update(unmatched_kwargs)
return final_args, new_kwargs
def _normalize_memo_key(
fn: Callable[..., Any], memo_key: MemoKeySpec
) -> PreparedMemoKeySpec | None:
"""Validate and compile per-parameter memo-key overrides once."""
if memo_key is None:
return None
View on GitHub (pinned to e84aa99b32)
Solutions
- Return a plain dict from the kwargs transform: dict(transformed)
- If returning items pairs, wrap with dict(sorted(kwargs.items()))
- Ensure the transform handles empty kwargs by returning {}
Example fix
# before
def key(**kw):
return sorted(kw.items())
# after
def key(**kw):
return dict(sorted(kw.items())) Defensive patterns
Strategy: validation
Validate before calling
def as_dict(result):
if not isinstance(result, dict):
raise TypeError("kwargs transform must return dict")
return result Type guard
def is_dict(x: object) -> TypeGuard[dict]:
return isinstance(x, dict) Prevention
- Return dict(...), never sorted(kwargs.items()) lists
- Annotate transform return type as dict
- Cover kwargs transforms with unit tests
When it happens
Trigger: @coco.fn with a memo_key transform for **kwargs (e.g. key "**" or varkw override) whose callable returns a list of pairs, None, or a non-dict mapping-like object, for a function accepting **kwargs.
Common situations: Returning sorted(kwargs.items()) (a list); returning a custom Mapping type; forgetting dict() around a filtered comprehension.
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 *args must return tuple, got {type(va
- 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/938963ed5b8cf523.
Report an issue: GitHub.