cocoindex-io/cocoindex · error · TypeError

{type(obj).__name__} cannot be used as a memoization key. Th

Error message

{type(obj).__name__} cannot be used as a memoization key. This type maintains internal state that is incompatible with memoization.

What it means

CocoIndex memoization fingerprints arguments to build a memoization key. Objects of types explicitly registered via coco.register_not_memo_keyable() are rejected because they carry internal state (e.g. open files, RNGs, generators) that would make an identical key even though the object differs. A TypeError is raised at call time when such an object is passed to a memoized function.

Source

Thrown at python/cocoindex/_internal/memo_fingerprint.py:224

    _memo_fns[typ] = _MemoFns(key_fn, state_fn)


def register_not_memo_keyable(typ: type) -> None:
    """Register a type as not memo-keyable.

    Use this for third-party types that maintain internal state incompatible
    with memoization, but which you cannot modify to inherit from `NotMemoKeyable`.

    Example:
        import cocoindex as coco
        from some_library import StatefulGenerator

        coco.register_not_memo_keyable(StatefulGenerator)
    """

    def _raise_not_memo_keyable(obj: object) -> typing.NoReturn:
        raise TypeError(
            f"{type(obj).__name__} cannot be used as a memoization key. "
            "This type maintains internal state that is incompatible with memoization."
        )

    _memo_fns[typ] = _MemoFns(_raise_not_memo_keyable)


def unregister_memo_key_function(typ: type) -> None:
    """Remove a previously registered memo key function (best-effort)."""

    _memo_fns.pop(typ, None)


def _stable_sort_key(v: Fingerprintable) -> tuple[typing.Any, ...]:
    """Return a totally-ordered key for canonical values.

    This is used to deterministically sort dict/set canonical encodings without
    relying on Python comparing heterogeneous values directly.

View on GitHub (pinned to e84aa99b32)

Solutions

  1. Remove the stateful object from the memoized function's arguments and pass only immutable, fingerprintable values (str, int, bytes, dataclasses of such).
  2. Pass a stable key derived from the object (e.g. its path, seed, or id) instead of the object itself.
  3. If the type is actually safe to key, remove it from the register_not_memo_keyable() registration in your own code.
  4. Disable memoization (memo=False) for functions that must accept stateful objects.

Example fix

// before
@coco.fn(memo=True)
async def run(gen: StatefulGenerator) -> int:
    return gen.next()
run(StatefulGenerator())

// after
@coco.fn(memo=True)
async def run(seed: int) -> int:
    gen = StatefulGenerator(seed)
    return gen.next()
run(42)
Defensive patterns

Strategy: type-guard

Validate before calling

if isinstance(arg, StatefulGenerator):
    raise ValueError("stateful object cannot be a memoized argument")

Type guard

def is_memo_keyable(obj: object) -> bool:
    return hasattr(obj, "__coco_memo_key__") or isinstance(obj, (str, int, float, bytes, bool, type(None), tuple))

Try / catch

try:
    result = await memoized_fn(arg)
except TypeError as e:
    if "memoization key" in str(e):
        result = await run_without_memo(arg)
    else:
        raise

Prevention

When it happens

Trigger: Passing an instance of a type registered with coco.register_not_memo_keyable() (like StatefulGenerator in the docstring example) as an argument to a function decorated with @coco.fn(memo=True).

Common situations: Developers wrapping stateful objects — generators, file handles, streams, connection objects — as arguments to memoized functions, often after the library author or their own code deliberately excluded that type from memoization keys.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of cocoindex-io/cocoindex@e84aa99b32 (2026-09-08). Data as JSON: /api/errors/bbc98099a2ae4ab5. Report an issue: GitHub.