langchain-ai/langchain · error · TypeError

Func was provided as a coroutine function, but afunc was als

Error message

Func was provided as a coroutine function, but afunc was also provided. If providing both, func should be a regular function to avoid ambiguity.

What it means

`RunnableLambda` accepts `func` (sync) and optionally `afunc` (async). If `func` itself is a coroutine function or async generator AND `afunc` is also provided, there would be two async candidates with no way to disambiguate, so the constructor raises a `TypeError`. The contract is: `func` sync + `afunc` async, or a single async `func`.

Source

Thrown at libs/core/langchain_core/runnables/base.py:4924

        Raises:
            TypeError: If the `func` is not a callable type.
            TypeError: If both `func` and `afunc` are provided.

        """
        func_for_name: Callable[..., Any]
        if afunc is not None:
            self.afunc = afunc
            func_for_name = afunc

        if is_async_callable(func) or is_async_generator(func):
            if afunc is not None:
                msg = (
                    "Func was provided as a coroutine function, but afunc was "
                    "also provided. If providing both, func should be a regular "
                    "function to avoid ambiguity."
                )
                raise TypeError(msg)
            self.afunc = func
            func_for_name = func
        elif callable(func):
            self.func = cast("Callable[[Input], Output]", func)
            func_for_name = func
        else:
            msg = (  # type: ignore[unreachable]
                "Expected a callable type for `func`."
                f"Instead got an unsupported type: {type(func)}"
            )
            raise TypeError(msg)

        try:
            if name is not None:
                self.name = name
            elif func_for_name.__name__ != "<lambda>":
                self.name = func_for_name.__name__
        except AttributeError:

View on GitHub (pinned to e32fa9a52e)

Solutions

  1. Provide a regular (non-async) function as `func` alongside `afunc`: `RunnableLambda(sync_fn, afunc=async_fn)`.
  2. If you only have an async function, pass it alone: `RunnableLambda(async_fn)` — it becomes the async implementation.
  3. Audit call sites that forward user callables to both parameters.

Example fix

// before
RunnableLambda(my_async_fn, afunc=my_async_fn)  # TypeError

// after
RunnableLambda(my_sync_fn, afunc=my_async_fn)
// or, async-only:
RunnableLambda(my_async_fn)
Defensive patterns

Strategy: validation

Validate before calling

import inspect

def valid_lambda_pair(func, afunc) -> bool:
    if afunc is None:
        return True
    return not inspect.iscoroutinefunction(func) and not inspect.isasyncgenfunction(func)

Type guard

import inspect
from langchain_core.runnables.utils import is_async_callable, is_async_generator

def is_sync_callable(fn) -> bool:
    return not is_async_callable(fn) and not is_async_generator(fn)

Try / catch

try:
    r = RunnableLambda(func, afunc=afunc)
except TypeError as e:
    if 'should be a regular function' in str(e):
        r = RunnableLambda(sync_version_of(func), afunc=afunc)
    else:
        raise

Prevention

When it happens

Trigger: `RunnableLambda(async_fn, afunc=async_fn)`; passing `afunc` while `func` is an `async def` (even the same function); copy-pasting an async function into both arguments.

Common situations: Refactoring a sync+async pair and accidentally making `func` async while leaving `afunc`; passing a decorator-wrapped async callable to both slots; library wrappers that forward `**kwargs` into `RunnableLambda`.

Related errors


AI-assisted analysis of langchain-ai/langchain@e32fa9a52e (2026-08-14). Data as JSON: /api/errors/91aba440ae0fe56e. Report an issue: GitHub.