PrefectHQ/fastmcp · error · RuntimeError
forward_raw() can only be called within a transformed tool
Error message
forward_raw() can only be called within a transformed tool
What it means
forward_raw() forwards a call to the parent (untransformed) tool, but it only works inside the replacement function of a transformed tool, which establishes a context variable via a ContextVar. If _current_tool is not set — i.e. forward_raw was called from arbitrary code or a plain test — the library raises RuntimeError to prevent forwarding with no valid parent tool.
Source
Thrown at fastmcp_slim/fastmcp/tools/tool_transform.py:98
This function bypasses all argument transformation and validation, calling the parent
tool directly with the provided arguments. Use this when you need to call the parent
with its original parameter names and structure.
For example, if the parent tool has args `x` and `y`, then `forward_raw(x=1,
y=2)` will call the parent tool with `x=1` and `y=2`.
Args:
**kwargs: Arguments to pass directly to the parent tool (using original names).
Returns:
The ToolResult from the parent tool execution.
Raises:
RuntimeError: If called outside a transformed tool context.
"""
tool = _current_tool.get()
if tool is None:
raise RuntimeError("forward_raw() can only be called within a transformed tool")
return await tool.parent_tool.run(kwargs)
@dataclass(kw_only=True)
class ArgTransform:
"""Configuration for transforming a parent tool's argument.
This class allows fine-grained control over how individual arguments are transformed
when creating a new tool from an existing one. You can rename arguments, change their
descriptions, add default values, or hide them from clients while passing constants.
Attributes:
name: New name for the argument. Use None to keep original name, or ... for no change.
description: New description for the argument. Use None to remove description, or ... for no change.
default: New default value for the argument. Use ... for no change.
default_factory: Callable that returns a default value. Cannot be used with default.
type: New type for the argument. Use ... for no change.View on GitHub (pinned to 1f02114297)
Solutions
- Call forward_raw() only inside the function you pass as the replacement to a tool transformation (from_tool / transform tool flow).
- If you need the parent tool behavior elsewhere, call the parent tool directly instead of forward_raw().
- In tests, invoke the transformed tool (which sets up the context) rather than calling forward_raw out of context; or use the library's test harness that establishes the transformed-tool context.
Example fix
// before
def my_helper(x):
return forward_raw(x) # RuntimeError: no transformed-tool context
// after
async def my_replacement(x):
# passed to from_tool(...) as the custom replacement function
result = await forward_raw(x)
return result * 2 Defensive patterns
Strategy: validation
Validate before calling
from fastmcp.tools.tool_transform import _current_tool
def forward_raw_available() -> bool:
return _current_tool.get() is not None Try / catch
try:
result = await forward_raw(**kwargs)
except RuntimeError as e:
if "transformed tool" in str(e):
raise RuntimeError("forward_raw must be called inside a tool-transform replacement function") from e
raise Prevention
- Only call forward_raw from within the custom function passed to from_tool.
- Never import forward_raw into application code or tests that run outside a transformed tool.
- Test forwarding behavior by invoking the transformed tool itself.
When it happens
Trigger: Calling forward_raw() (or a forward wrapper built on it) from a regular function not registered via ToolTransform.from_tool; importing and invoking forward_raw in unit tests without the transformed-tool context; storing the forwarding function and calling it later after the transform context has exited.
Common situations: Writing custom replacement functions for transformed tools and accidentally calling forward_raw outside the closure passed to transform_tool/from_tool; copy-pasting forward_raw into application code; tests that call the forwarding function directly instead of through the transformed tool.
Related errors
- forward() can only be called within a transformed tool
- No access token available. Cannot perform OBO exchange.
- FastMCP instance is no longer available
- Unexpected CreateTaskResult: Context calls should not have t
- request_id is not available because the MCP session has not
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/c7194e370996ebe0.
Report an issue: GitHub.