{"record":{"id":"ea1dedf75e3a4f2e","repo":"cocoindex-io/cocoindex","slug":"expected-self-argument","errorCode":null,"errorMessage":"Expected self argument","messagePattern":"Expected self argument","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/cocoindex/_internal/function.py","lineNumber":1475,"sourceCode":"                parent_ctx._core_fn_call_ctx.join_child(fn_ctx)\n\n    async def _execute(\n        self,\n        async_ctx: core.AsyncContext,\n        *args: P.args,\n        **kwargs: P.kwargs,\n    ) -> R_co:\n        \"\"\"Execute via batcher/runner.\"\"\"\n        if not self._is_scheduled:\n            if self._orig_async_fn is not None:\n                return await self._orig_async_fn(*args, **kwargs)  # type: ignore\n            else:\n                assert self._orig_sync_fn is not None\n                return await asyncio.to_thread(self._orig_sync_fn, *args, **kwargs)\n\n        if self._has_self:\n            if len(args) < 1:\n                raise ValueError(\"Expected self argument\")\n            self_obj = args[0]\n            actual_args = args[1:]\n        else:\n            self_obj = None\n            actual_args = args\n\n        # Parse args based on mode\n        if self._batching:\n            if len(actual_args) < 1:\n                raise ValueError(\"Expected at least one input argument\")\n            input_val = actual_args[0]\n            extra_args = tuple(actual_args[1:])\n            extra_kwargs = dict(kwargs)\n        else:\n            # Runner-only mode: wrap (args, kwargs) as single input\n            input_val = (actual_args, kwargs)\n            extra_args = ()\n            extra_kwargs = {}","sourceCodeStart":1457,"sourceCodeEnd":1493,"githubUrl":"https://github.com/cocoindex-io/cocoindex/blob/e84aa99b3292c5270a4b313b2a7137ad9ce8ab3b/python/cocoindex/_internal/function.py#L1457-L1493","documentation":"When a Function was declared to take a self argument (e.g. a method used via coco.fn), _execute expects the first positional argument to be the bound self instance. It throws ValueError when zero positional args are supplied, because self cannot be extracted.","triggerScenarios":"Calling a coco.fn-wrapped method (or triggering its execution through __call__ / the core processor) with no positional arguments when self._has_self is True — e.g. calling the unbound function with only keyword args, or invoking a method-style fn without its instance.","commonSituations":"Wrapping an instance method as a standalone @coco.fn and then calling it without the instance; passing all inputs as kwargs so the positional slot for self is empty; refactoring a plain function into a method without updating call sites.","solutions":["Pass the instance as the first positional argument when calling the wrapped function.","If the fn is not meant to be a method, re-declare it so _has_self is False (plain function).","Use the bound method (obj.method) rather than the unbound class function so self is already bound."],"exampleFix":"// before\nresult = await my_fn(arg1=1)  # self missing\n// after\nresult = await my_fn(obj, 1)  # or: await obj.method(1)","handlingStrategy":"validation","validationCode":"if fn_meta.has_self and len(positional_args) < 1:\n    raise ValueError(\"instance required as first argument\")","typeGuard":"def has_self_arg(fn): return inspect.signature(fn).parameters and 'self' in inspect.signature(fn).parameters","tryCatchPattern":"try:\n    result = await wrapped_fn(*args)\nexcept ValueError as e:\n    if \"Expected self argument\" in str(e):\n        result = await wrapped_fn(instance, *args)","preventionTips":["Call bound methods (obj.method) rather than unbound functions.","Never pass all arguments as kwargs for method-style coco.fn wrappers."],"tags":["python","argument-mismatch","function-call"],"backgroundTag":"missing-required-argument","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"}