PrefectHQ/fastmcp · error
Function missing parameters required after transformation: {
Error message
Function missing parameters required after transformation: {', '.join(sorted(missing_params))}. Function declares: {', '.join(sorted(fn_params))} What it means
When a custom replacement function doesn't accept **kwargs, from_tool() requires the function's signature to cover every parameter that exists after transformation. If transformed_params contains names the function doesn't declare, ValueError is raised listing the missing parameters and what the function declares.
Source
Thrown at fastmcp_slim/fastmcp/tools/tool_transform.py:546
final_schema = schema
else:
# parsed fn is not none here
parsed_fn = cast(ParsedFunction, parsed_fn)
# User provided custom function - merge schemas
final_fn = transform_fn
has_kwargs = cls._function_has_kwargs(transform_fn)
# Validate function parameters against transformed schema
fn_params = set(parsed_fn.input_schema.get("properties", {}).keys())
transformed_params = set(schema.get("properties", {}).keys())
if not has_kwargs:
# Without **kwargs, function must declare all transformed params
# Check if function is missing any parameters required after transformation
missing_params = transformed_params - fn_params
if missing_params:
raise ValueError(
f"Function missing parameters required after transformation: "
f"{', '.join(sorted(missing_params))}. "
f"Function declares: {', '.join(sorted(fn_params))}"
)
# ArgTransform takes precedence over function signature
# Start with function schema as base, then override with transformed schema
final_schema = cls._merge_schema_with_precedence(
parsed_fn.input_schema, schema
)
else:
# With **kwargs, function can access all transformed params
# ArgTransform takes precedence over function signature
# No validation needed - kwargs makes everything accessible
# Start with function schema as base, then override with transformed schema
final_schema = cls._merge_schema_with_precedence(
parsed_fn.input_schema, schemaView on GitHub (pinned to 1f02114297)
Solutions
- Add the missing parameter names to the replacement function's signature.
- Or accept **kwargs in the replacement function so all transformed params are forwarded.
- Or adjust transform_args so the resulting parameter names match the function's declared parameters.
Example fix
// before
async def run(query): ...
from_tool(tool, fn=run, transform_args={"query": ArgTransform(name="q")})
// after
async def run(q): ...
# or: async def run(**kwargs): ... Defensive patterns
Strategy: validation
Validate before calling
import inspect
def check_fn_covers(tool, transform_args: dict, fn) -> None:
transformed = set(transform_args) | set(tool.parameters["properties"])
sig = inspect.signature(fn)
if sig.parameters.get("kwargs").kind is not inspect.Parameter.VAR_KEYWORD:
missing = {p for p in transformed if p not in sig.parameters}
if missing:
raise ValueError(f"fn missing params: {sorted(missing)}") Try / catch
try:
t = ParentTool.from_tool(tool, fn=fn, transform_args=ta)
except ValueError as e:
if "missing parameters" in str(e):
log.error("Update fn signature or add **kwargs: %s", e)
raise Prevention
- Accept **kwargs in replacement functions to stay forward-compatible with transform changes.
- Keep the fn signature and transform_args in the same commit so they can't drift.
- Mirror the final transformed parameter names exactly in the fn signature.
When it happens
Trigger: Providing fn= to from_tool with a fixed-signature function while transform_args renames/adds parameters the function lacks; the transform makes a hidden param's new name absent from the function signature; forgetting that ArgTransform renames change required parameter names.
Common situations: Writing a slim wrapper function and forgetting a renamed argument; transformation later updated to add new params while the custom fn wasn't updated.
Related errors
- ToolTransform has duplicate target name {target!r}: both {se
- forward() can only be called within a transformed tool
- forward_raw() can only be called within a transformed tool
- Cannot specify both 'default' and 'default_factory' in ArgTr
- default_factory can only be used with hide=True. Visible par
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/9f291ab0f37073b9.
Report an issue: GitHub.