PrefectHQ/fastmcp · error
Multiple arguments would be mapped to the same names: {', '.
Error message
Multiple arguments would be mapped to the same names: {', '.join(sorted(duplicates))} What it means
from_tool() computes the final exposed name of every transformed argument (via name= or the resulting name) and rejects transforms where two or more arguments would collide on the same exposed name, since the output schema cannot declare duplicate properties. Raises ValueError with the duplicated names.
Source
Thrown at fastmcp_slim/fastmcp/tools/tool_transform.py:590
if transform.hide:
continue
if transform.name is not NotSet:
new_names.append(transform.name)
else:
new_names.append(old_name)
# Check for duplicate names after transformation
name_counts = {}
for arg_name in new_names:
name_counts[arg_name] = name_counts.get(arg_name, 0) + 1
duplicates = [
arg_name for arg_name, count in name_counts.items() if count > 1
]
if duplicates:
raise ValueError(
f"Multiple arguments would be mapped to the same names: "
f"{', '.join(sorted(duplicates))}"
)
final_name = name or tool.name
final_version = version if not isinstance(version, NotSetT) else tool.version
final_description = (
description if not isinstance(description, NotSetT) else tool.description
)
final_title = title if not isinstance(title, NotSetT) else tool.title
final_meta = _apply_meta_override(tool.meta, meta)
final_annotations = (
annotations if not isinstance(annotations, NotSetT) else tool.annotations
)
transformed_tool = cls(
fn=final_fn,
return_type=parsed_fn.return_type if parsed_fn is not None else None,View on GitHub (pinned to 1f02114297)
Solutions
- Give each ArgTransform a unique name=, or remove/rename the colliding entry.
- If merging params intentionally, hide the redundant params and accept a single visible one.
- Keep one entry without name= so it keeps its parent name, and rename only the other.
Example fix
// before
transform_args={"a": ArgTransform(name="x"), "b": ArgTransform(name="x")}
// after
transform_args={"a": ArgTransform(name="x"), "b": ArgTransform(name="y")} Defensive patterns
Strategy: validation
Validate before calling
def check_name_collisions(transform_args: dict) -> None:
names = [t.name or src for src, t in transform_args.items()]
dupes = {n for n in names if names.count(n) > 1}
if dupes:
raise ValueError(f"Duplicate exposed names: {sorted(dupes)}") Try / catch
try:
t = ParentTool.from_tool(tool, transform_args=ta)
except ValueError as e:
if "same names" in str(e):
log.error("Resolve duplicate exposed names: %s", e)
raise Prevention
- Generate exposed names programmatically (e.g. prefix per source param) instead of hand-typing aliases.
- When merging params, hide the redundant ones instead of aliasing both to one name.
- Add a unit test asserting unique final names for your transform set.
When it happens
Trigger: Two ArgTransforms in transform_args both set name="same_name" (e.g. merging two params into one without removing the other); an explicit name that collides with another param's final name.
Common situations: Attempting to collapse several parent params into one alias while forgetting to drop or hide the others; bulk-generated transforms reusing an alias.
Related errors
- Cannot specify both 'default' and 'default_factory' in ArgTr
- default_factory can only be used with hide=True. Visible par
- 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
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/d06850b4419bd838.
Report an issue: GitHub.