{"record":{"id":"d07f59409839ed4b","repo":"cocoindex-io/cocoindex","slug":"unknown-memo-key-parameter-s-for-qualified-name-d07f59","errorCode":null,"errorMessage":"Unknown memo_key parameter(s) for {qualified_name(fn)}(): {unknown}","messagePattern":"Unknown memo_key parameter\\(s\\) for (.+?)\\(\\): (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/_internal/function.py","lineNumber":546,"sourceCode":"    if memo_key is None:\n        return None\n\n    normalized = dict(memo_key)\n    if not normalized:\n        return None\n\n    sig = inspect.signature(fn)\n    param_names = {param.name for param in sig.parameters.values()}\n    unknown = sorted(name for name in normalized if name not in param_names)\n    if unknown:\n        raise ValueError(\n            f\"Unknown memo_key parameter(s) for {qualified_name(fn)}(): \"\n            + \", \".join(unknown)\n        )\n\n    for name, transform in normalized.items():\n        if transform is not None and not callable(transform):\n            raise TypeError(\n                f\"memo_key[{name!r}] for {qualified_name(fn)}() must be a callable or None\"\n            )\n\n    positional: list[MemoKeyTransform | None | NotSetType] = []\n    varargs_override: MemoKeyTransform | None | NotSetType = NOT_SET\n    varkw_override: MemoKeyTransform | None | NotSetType = NOT_SET\n\n    for param in sig.parameters.values():\n        if param.kind in (\n            inspect.Parameter.POSITIONAL_ONLY,\n            inspect.Parameter.POSITIONAL_OR_KEYWORD,\n        ):\n            if param.name in normalized:\n                positional.append(normalized[param.name])\n            else:\n                positional.append(NOT_SET)\n        elif param.kind == inspect.Parameter.VAR_POSITIONAL:\n            if param.name in normalized:","sourceCodeStart":528,"sourceCodeEnd":564,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/_internal/function.py#L528-L564","documentation":"This is a near-duplicate of the _normalize_memo_key ValueError but raised from a later diagnostic path in the same validation, with the unknown names formatted via a single interpolated value. It fires when memo_key references parameters absent from the decorated function's signature.","triggerScenarios":"Same as error 37: @coco.fn(memo_key={...}) containing a name not in fn's parameters, reached via the alternate validation/reporting branch in _normalize_memo_key (called from __init__ and tests).","commonSituations":"Typos, stale parameter names after refactoring, or reused memo_key dicts across different functions.","solutions":["Fix the memo_key keys to match declared parameters","Keep memo_key specs co-located with the function definition to catch drift in review","Add a unit test decorating the function at import time so the ValueError surfaces early"],"exampleFix":"# before\n@coco.fn(memo_key={\"old_param\": None})\nasync def f(new_param: str): ...\n\n# after\n@coco.fn(memo_key={\"new_param\": None})\nasync def f(new_param: str): ...","handlingStrategy":"validation","validationCode":"import inspect\nassert set(memo_key) <= set(inspect.signature(fn).parameters), \"memo_key names must match fn parameters\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reuse a shared helper to build memo_key specs per function","Run a quick smoke import of decorated modules in CI","Avoid sharing one memo_key dict across functions with different signatures"],"tags":["memoization","decorator-config","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b","analyzedAt":"2026-09-08T15:59:19.997Z","contentChangedAt":"2026-09-08T15:59:19.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}