{"record":{"id":"975db423c65d39c6","repo":"pathwaycom/pathway","slug":"the-function-is-a-coroutine-you-can-t-use-syncexe","errorCode":null,"errorMessage":"The function is a coroutine. You can't use SyncExecutor.","messagePattern":"The function is a coroutine\\. You can't use SyncExecutor\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/pathway/internals/udfs/__init__.py","lineNumber":222,"sourceCode":"            else:\n                if not isinstance(wrapped_sig_return_type, dt.List):\n                    raise ValueError(\n                        f\"A batch UDF has to return a list but is annotated as returning {sig_return_type}\"\n                    )\n                return wrapped_sig_return_type.wrapped\n\n        return return_type\n\n    def _wrap_function(self) -> Callable:\n        func = self.executor._wrap(self.__wrapped__)\n        if self.cache_strategy is not None:\n            func = with_cache_strategy(func, self.cache_strategy)\n        return func\n\n    def _prepare_executor(self, executor: Executor) -> Executor:\n        is_coroutine = inspect.iscoroutinefunction(self.__wrapped__)\n        if is_coroutine and isinstance(executor, SyncExecutor):\n            raise ValueError(\"The function is a coroutine. You can't use SyncExecutor.\")\n        if isinstance(executor, AutoExecutor):\n            return async_executor() if is_coroutine else udfs.sync_executor()\n        return executor\n\n    def __call__(self, *args, **kwargs) -> expr.ColumnExpression:\n        return self.executor._apply_expression_type(\n            self.func,\n            return_type=self._get_return_type(),\n            propagate_none=self.propagate_none,\n            deterministic=self.deterministic,\n            max_batch_size=self.max_batch_size,\n            **self.executor.additional_expression_args(),\n            args=args,\n            kwargs=kwargs,\n        )\n\n\nclass UDFFunction(UDF):","sourceCodeStart":204,"sourceCodeEnd":240,"githubUrl":"https://github.com/pathwaycom/pathway/blob/fa2f74a4649b7c5908690cf60137263d8d80de5f/python/pathway/internals/udfs/__init__.py#L204-L240","documentation":"ValueError raised in _prepare_executor when the wrapped function is a coroutine function (async def) but the executor is SyncExecutor. Sync executors call the function directly and cannot await coroutines.","triggerScenarios":"@pw.udf(executor=pw.udfs.sync_executor()) decorating an async def function; passing an explicit SyncExecutor (or subclass) for a coroutine UDF. Note AutoExecutor would auto-select an async executor, so this only fires when sync_executor was requested explicitly.","commonSituations":"Converting a sync UDF to async def while keeping an explicit sync_executor in shared decorator config; copy-pasted decorator parameters; custom executor subclassing SyncExecutor used with async functions.","solutions":["Use an async executor: pw.udfs.async_executor(), or omit executor to let AutoExecutor pick","Convert the coroutine back to a sync def if you must keep sync_executor","In shared UDF factories, select executor based on inspect.iscoroutinefunction(func)"],"exampleFix":"// before\n@pw.udf(executor=pw.udfs.sync_executor())\nasync def f(x: int) -> int:\n    return await fetch(x)\n\n// after\n@pw.udf(executor=pw.udfs.async_executor())\nasync def f(x: int) -> int:\n    return await fetch(x)","handlingStrategy":"validation","validationCode":"import inspect\nfrom pathway.internals.udfs import SyncExecutor\n\ndef assert_executor_matches(fn, executor):\n    if inspect.iscoroutinefunction(fn):\n        assert not isinstance(executor, SyncExecutor), 'async def needs an async executor'\n    return executor","typeGuard":"import inspect\n\ndef is_coroutine_fn(fn) -> bool:\n    return inspect.iscoroutinefunction(fn)","tryCatchPattern":null,"preventionTips":["Let AutoExecutor choose when unsure (omit executor=)","Select executor from inspect.iscoroutinefunction in shared decorators","Fail fast at import time by constructing UDFs eagerly in tests"],"tags":["pathway","udf","async","executor"],"backgroundTag":null,"analyzedSha":"fa2f74a4649b7c5908690cf60137263d8d80de5f","analyzedAt":"2026-08-15T01:48:17.006Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}