PrefectHQ/fastmcp · error
default_factory can only be used with hide=True. Visible par
Error message
default_factory can only be used with hide=True. Visible parameters must use static 'default' values since JSON schema cannot represent dynamic factories.
What it means
ArgTransform requires default_factory to be paired with hide=True. A visible parameter would need its default expressed in the JSON schema sent to clients, but a callable default cannot be serialized to a schema, so the library rejects the combination with ValueError.
Source
Thrown at fastmcp_slim/fastmcp/tools/tool_transform.py:194
default_factory: Callable[[], Any] | NotSetT = NotSet
type: Any | NotSetT = NotSet
hide: bool = False
required: Literal[True] | NotSetT = NotSet
examples: Any | NotSetT = NotSet
def __post_init__(self):
"""Validate that only one of default or default_factory is provided."""
has_default = self.default is not NotSet
has_factory = self.default_factory is not NotSet
if has_default and has_factory:
raise ValueError(
"Cannot specify both 'default' and 'default_factory' in ArgTransform. "
"Use either 'default' for a static value or 'default_factory' for a callable."
)
if has_factory and not self.hide:
raise ValueError(
"default_factory can only be used with hide=True. "
"Visible parameters must use static 'default' values since JSON schema "
"cannot represent dynamic factories."
)
if self.required is True and (has_default or has_factory):
raise ValueError(
"Cannot specify 'required=True' with 'default' or 'default_factory'. "
"Required parameters cannot have defaults."
)
if self.hide and self.required is True:
raise ValueError(
"Cannot specify both 'hide=True' and 'required=True'. "
"Hidden parameters cannot be required since clients cannot provide them."
)
if self.required is False:View on GitHub (pinned to 1f02114297)
Solutions
- Add hide=True if the parameter should not appear in the transformed schema.
- Replace default_factory with a static default= if the parameter must remain visible.
- Have the replacement function compute the value itself (via forward_raw / parent call) and drop default_factory.
Example fix
// before ArgTransform(name="api_key", default_factory=lambda: make_key()) // after ArgTransform(name="api_key", default_factory=lambda: make_key(), hide=True)
Defensive patterns
Strategy: validation
Validate before calling
def check_factory_hidden(t: ArgTransform) -> None:
if t.default_factory is not NotSet and not t.hide:
raise ValueError("default_factory requires hide=True") Try / catch
try:
t = ArgTransform(default_factory=make)
except ValueError:
t = ArgTransform(default_factory=make, hide=True) Prevention
- Remember: dynamic defaults are invisible to JSON schema — they only work on hidden params.
- If the param must be visible, compute its value inside the replacement function instead.
- Review ArgTransform definitions for default_factory without hide during code review.
When it happens
Trigger: ArgTransform(default_factory=some_callable) without hide=True (hide defaults to False).
Common situations: Wanting a per-call generated default (timestamp, uuid, token) while still exposing the parameter in the transformed schema; misunderstanding that factories only work for hidden params.
Related errors
- Cannot specify both 'default' and 'default_factory' in ArgTr
- Cannot specify 'required=True' with 'default' or 'default_fa
- Cannot specify both 'hide=True' and 'required=True'. Hidden
- Cannot specify 'required=False'. Set a default value instead
- Unknown arguments in transform_args: {', '.join(sorted(unkno
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/0c1737d231728189.
Report an issue: GitHub.