microsoft/autogen · error · RuntimeError

Failed to get user input: {str(e)}

Error message

Failed to get user input: {str(e)}

What it means

UserProxyAgent wraps any exception raised by the configured input_func (async or sync) in this RuntimeError. It re-raises asyncio.CancelledError untouched, so genuine failures come from the callback itself: wrong signature, missing runtime dependency, or an error in the input UI code.

Source

Thrown at python/packages/autogen-agentchat/src/autogen_agentchat/agents/_user_proxy_agent.py:202

        return None

    async def _get_input(self, prompt: str, cancellation_token: Optional[CancellationToken]) -> str:
        """Handle input based on function signature."""
        try:
            if self._is_async:
                # Cast to AsyncInputFunc for proper typing
                async_func = cast(AsyncInputFunc, self.input_func)
                return await async_func(prompt, cancellation_token)
            else:
                # Cast to SyncInputFunc for proper typing
                sync_func = cast(SyncInputFunc, self.input_func)
                loop = asyncio.get_event_loop()
                return await loop.run_in_executor(None, sync_func, prompt)

        except asyncio.CancelledError:
            raise
        except Exception as e:
            raise RuntimeError(f"Failed to get user input: {str(e)}") from e

    async def on_messages(self, messages: Sequence[BaseChatMessage], cancellation_token: CancellationToken) -> Response:
        async for message in self.on_messages_stream(messages, cancellation_token):
            if isinstance(message, Response):
                return message
        raise AssertionError("The stream should have returned the final result.")

    async def on_messages_stream(
        self, messages: Sequence[BaseChatMessage], cancellation_token: CancellationToken
    ) -> AsyncGenerator[BaseAgentEvent | BaseChatMessage | Response, None]:
        """Handle incoming messages by requesting user input."""
        try:
            # Check for handoff first
            handoff = self._get_latest_handoff(messages)
            prompt = (
                f"Handoff received from {handoff.source}. Enter your response: " if handoff else "Enter your response: "
            )

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Run the input_func standalone with a prompt (and cancellation token for async) to see the original exception; the message embeds str(e).
  2. Match the expected signature: async callbacks take (prompt, cancellation_token); sync callbacks take (prompt).
  3. Handle EOF/stdin-closed cases inside the callback (e.g. sys.stdin reading guarded) for non-interactive environments.
  4. Ensure any UI/console dependency the callback uses is installed where the agent runs.

Example fix

// before
def input(prompt: str, cancellation_token) -> str:  # sync: token not passed -> TypeError
    return input(prompt)

// after
def read_input(prompt: str) -> str:
    return builtins_input(prompt)

agent = UserProxyAgent(name="user", input_func=read_input)
Defensive patterns

Strategy: try-catch

Validate before calling

import inspect

def input_callback_ok(fn) -> bool:
    params = list(inspect.signature(fn).parameters)
    if inspect.iscoroutinefunction(fn):
        return len(params) == 2  # (prompt, cancellation_token)
    return len(params) == 1  # (prompt,)

assert input_callback_ok(input_func), "input_func signature mismatch"

Type guard

import inspect
from autogen_agentchat.agents import UserProxyAgent

def matches_input_contract(fn) -> bool:
    if inspect.iscoroutinefunction(fn):
        try:
            inspect.signature(fn).bind("prompt", None)
            return True
        except TypeError:
            return False
    try:
        inspect.signature(fn).bind("prompt")
        return True
    except TypeError:
        return False

Try / catch

try:
    async for msg in user_proxy.on_messages_stream(msgs, ct):
        ...
except RuntimeError as e:
    if "Failed to get user input" in str(e):
        # str(e) embeds the original callback error; log and surface to user
        log.error("input callback failed: %s", e.__cause__)
    raise

Prevention

When it happens

Trigger: input_func raising because its signature doesn't match how it's invoked — async callbacks are awaited as f(prompt, cancellation_token), sync ones run in an executor as f(prompt); or the console/UI code inside the callback throwing (KeyboardInterrupt handling, EOF on stdin, missing widget).

Common situations: Callbacks declared def input(prompt: str, cancellation_token) that also try to accept extra args, or async def input(prompt) that internally breaks; stdin EOF in non-interactive CI; UI library not installed in the runtime environment.

Related errors


AI-assisted analysis of microsoft/autogen@027ecf0a37 (2026-08-15). Data as JSON: /api/errors/36baea9acd20a148. Report an issue: GitHub.