{"record":{"id":"7edd77c10bf8bfc1","repo":"PrefectHQ/fastmcp","slug":"cannot-specify-name-both-as-first-argument-and-key-7edd77","errorCode":null,"errorMessage":"Cannot specify name both as first argument and keyword","messagePattern":"Cannot specify name both as first argument and keyword","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/tools/function_tool.py","lineNumber":616,"sourceCode":"            annotations=annotations,\n            meta=meta,\n            task=task,\n            timeout=timeout,\n            auth=auth,\n            run_in_thread=run_in_thread,\n        )\n        target = fn.__func__ if isinstance(fn, staticmethod | MethodType) else fn\n        cast(Any, target).__fastmcp__ = metadata\n        return fn\n\n    def decorator(fn: F, tool_name: str | None) -> F:\n        return attach_metadata(fn, tool_name)\n\n    if inspect.isroutine(name_or_fn):\n        return decorator(name_or_fn, name)\n    elif isinstance(name_or_fn, str):\n        if name is not None:\n            raise TypeError(\"Cannot specify name both as first argument and keyword\")\n        tool_name = name_or_fn\n    elif name_or_fn is None:\n        tool_name = name\n    else:\n        raise TypeError(f\"Invalid first argument: {type(name_or_fn)}\")\n\n    def wrapper(fn: F) -> F:\n        return decorator(fn, tool_name)\n\n    return wrapper\n","sourceCodeStart":598,"sourceCodeEnd":627,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/tools/function_tool.py#L598-L627","documentation":"The @tool decorator supports @tool(name) (positional string) or @tool(name=...), but not both. When name_or_fn is a string and the name keyword is also set, it raises TypeError to resolve the ambiguity.","triggerScenarios":"@tool(\"my_tool\", name=\"my_tool\") or @tool(\"my_tool\", name=\"other\") — any call with a positional string first argument plus a non-None name keyword.","commonSituations":"Migrating from @tool(name=...) style to positional style and leaving both; IDE autofill adding name= alongside an existing positional name; wrapping decorators forwarding both forms.","solutions":["Keep only one: drop the name= keyword if the positional string is the desired name","Or drop the positional string and use name=\"...\" only"],"exampleFix":"// before\n@tool(\"my_tool\", name=\"my_tool\")\ndef fn(x: int) -> int: ...\n// after\n@tool(\"my_tool\")\ndef fn(x: int) -> int: ...","handlingStrategy":"validation","validationCode":"def check_tool_decorator_args(name_or_fn, name=None):\n    if isinstance(name_or_fn, str) and name is not None:\n        raise TypeError('name given both positionally and as keyword')","typeGuard":null,"tryCatchPattern":"try:\n    tool = tool_decorator('my_tool', name=kw_name)\nexcept TypeError as e:\n    if 'both as first argument and keyword' in str(e):\n        tool = tool_decorator('my_tool')","preventionTips":["Use one naming style: prefer @tool(name=\"...\") everywhere","Never forward both *args and name= from wrapper decorators","Lint for @tool calls mixing positional strings with name="],"tags":["python","decorators","api-misuse","duplicate-argument"],"backgroundTag":"duplicate-parameter","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}