FoundationAgents/MetaGPT · error · ValueError
`req` must be provided as a keyword argument.
Error message
`req` must be provided as a keyword argument.
What it means
The exp_pool @enable_exp_pool decorator requires the wrapped function's request to arrive as a keyword argument named exactly `req`. _validate_params checks `"req" in self.kwargs` and raises ValueError otherwise, because the pool serializes and retrieves experiences keyed on that kwarg. Passing req positionally, or naming it differently, fails validation before the function runs.
Source
Thrown at metagpt/exp_pool/decorator.py:197
self.exp_manager.create_exp(exp)
self._log_exp(exp)
@staticmethod
def choose_wrapper(func, wrapped_func):
"""Choose how to run wrapped_func based on whether the function is asynchronous."""
async def async_wrapper(*args, **kwargs):
return await wrapped_func(args, kwargs)
def sync_wrapper(*args, **kwargs):
NestAsyncio.apply_once()
return asyncio.get_event_loop().run_until_complete(wrapped_func(args, kwargs))
return async_wrapper if asyncio.iscoroutinefunction(func) else sync_wrapper
def _validate_params(self):
if "req" not in self.kwargs:
raise ValueError("`req` must be provided as a keyword argument.")
def _generate_tag(self) -> str:
"""Generates a tag for the self.func.
"ClassName.method_name" if the first argument is a class instance, otherwise just "function_name".
"""
if self.args and hasattr(self.args[0], "__class__"):
cls_name = type(self.args[0]).__name__
return f"{cls_name}.{self.func.__name__}"
return self.func.__name__
async def _build_context(self) -> str:
self.context_builder.exps = self._exps
return await self.context_builder.build(self.kwargs["req"])
View on GitHub (pinned to 11cdf466d0)
Solutions
- Call the decorated function with the keyword: await obj.run(req=ExperienceRequest(...)) (or whatever request object the function expects).
- Rename the function's parameter to req if you control the definition, so positional-style keyword calls line up.
- If you cannot change callers, wrap the function: define an adapter that accepts your name and forwards req=... to the decorated target.
Example fix
# before
@enable_exp_pool
class _Run:
async def run(self, req): ...
await runner.run("some question") # ValueError: `req` must be provided as a keyword argument.
# after
await runner.run(req="some question") Defensive patterns
Strategy: validation
Validate before calling
# the decorator requires this exact keyword; check your call site before invoking assert "req" in kwargs_of_call, "decorated function must be called with req=... as a keyword argument" await obj.run(req=req_obj)
Try / catch
try:
await runner.run(req=q)
except ValueError as e:
if "`req` must be provided" in str(e):
raise TypeError("call exp-pool-decorated functions with req=<request> keyword") from e
raise Prevention
- Adopt the convention `req` everywhere: decorated function parameters and call sites use the same name.
- Add a unit test that calls each decorated function once — the ValueError surfaces immediately in CI, not in production.
- When wrapping third-party functions with @enable_exp_pool, write a thin adapter that forwards req=...
When it happens
Trigger: Decorating a method and calling it as obj.run(query) (positional) or obj.run(request=query) instead of obj.run(req=query); the decorator applies to both sync and async functions, both wrappers enforce the contract.
Common situations: Adding the decorator to an existing method whose parameters use a different name; refactoring call sites and dropping the `req=` keyword; copying examples that predate the keyword-argument requirement.
Related errors
- To use the experience pool, you need to install the rag modu
- Missing fields: {missing_fields}
- use `review` after `fill`
- Data type not supported for metadata extraction.
- Table not created yet, please add data first.
AI-assisted analysis of FoundationAgents/MetaGPT@11cdf466d0 (2026-08-14).
Data as JSON: /api/errors/7565b7d5ea2b6f7e.
Report an issue: GitHub.