microsoft/autogen · error · ValueError

args is required for {type}

Error message

args is required for {type}

What it means

McpActor.call() dispatches per command type; for 'call_tool', 'read_resource' and 'get_prompt' it must extract name/kwargs from an args dict. If args is None for one of these, ValueError('args is required for {type}') is raised. This is an internal API contract error — callers must pass a dict with at least 'name' (and 'kargs' for parameters).

Source

Thrown at python/packages/autogen-ext/src/autogen_ext/tools/mcp/_actor.py:109

        return self._initialize_result

    async def initialize(self) -> None:
        if not self._active:
            self._active = True
            self._actor_task = asyncio.create_task(self._run_actor())

    async def call(self, type: str, args: McpActorArgs | None = None) -> McpFuture:
        if not self._active:
            raise RuntimeError("MCP Actor not running, call initialize() first")
        if self._actor_task and self._actor_task.done():
            raise RuntimeError("MCP actor task crashed", self._actor_task.exception())
        fut: asyncio.Future[McpFuture] = asyncio.Future()
        if type in {"list_tools", "list_prompts", "list_resources", "list_resource_templates", "shutdown"}:
            await self._command_queue.put({"type": type, "future": fut})
            res = await fut
        elif type in {"call_tool", "read_resource", "get_prompt"}:
            if args is None:
                raise ValueError(f"args is required for {type}")
            name = args.get("name", None)
            kwargs = args.get("kargs", {})
            if type == "call_tool" and name is None:
                raise ValueError("name is required for call_tool")
            elif type == "read_resource":
                uri = kwargs.get("uri", None)
                if uri is None:
                    raise ValueError("uri is required for read_resource")
                await self._command_queue.put({"type": type, "uri": uri, "future": fut})
            elif type == "get_prompt":
                if name is None:
                    raise ValueError("name is required for get_prompt")
                prompt_args = kwargs.get("arguments", None)
                await self._command_queue.put({"type": type, "name": name, "args": prompt_args, "future": fut})
            else:  # call_tool
                await self._command_queue.put({"type": type, "name": name, "args": kwargs, "future": fut})
            res = await fut
        else:

View on GitHub (pinned to 027ecf0a37)

Solutions

  1. Pass a dict: await actor.call('call_tool', args={'name': 'search', 'kargs': {'query': 'x'}}).
  2. For read_resource use args={'kargs': {'uri': 'file://...'}}; for get_prompt use args={'name': 'prompt_id', 'kargs': {'arguments': {...}}}.
  3. Prefer the higher-level session/workbench APIs which build these dicts for you.

Example fix

# before
result = await actor.call("call_tool")

# after
result = await actor.call("call_tool", args={"name": "search", "kargs": {"query": "hello"}})
Defensive patterns

Strategy: validation

Validate before calling

NEEDS_ARGS = {"call_tool", "read_resource", "get_prompt"}
if cmd in NEEDS_ARGS and not isinstance(args, dict):
    raise ValueError(f"args dict required for {cmd}")

Type guard

from typing import Any, TypeGuard

def is_actor_args(value: Any) -> TypeGuard[dict]:
    return isinstance(value, dict)

Prevention

When it happens

Trigger: Calling actor.call('call_tool') / actor.call('read_resource') / actor.call('get_prompt') with args omitted or explicitly None. List-style commands (list_tools etc.) do not need args and are unaffected.

Common situations: Writing a thin wrapper around the actor and forwarding an empty call; passing a positional string instead of a dict; forgetting the args dict when migrating code from a client API that took name as a separate parameter.

Related errors


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