diff --git a/arcade/arcade/core/catalog.py b/arcade/arcade/core/catalog.py index d0a1825f..6fe3296e 100644 --- a/arcade/arcade/core/catalog.py +++ b/arcade/arcade/core/catalog.py @@ -575,7 +575,14 @@ def extract_field_info(param: inspect.Parameter) -> ToolParamInfo: elif len(str_annotations) == 1: param_info.description = str_annotations[0] elif len(str_annotations) == 2: - param_info.name = str_annotations[0] + new_name = str_annotations[0] + if not new_name.isidentifier(): + raise ToolDefinitionError( + f"Invalid parameter name: '{new_name}' is not a valid identifier. " + "Identifiers must start with a letter or underscore, " + "and can only contain letters, digits, or underscores." + ) + param_info.name = new_name param_info.description = str_annotations[1] else: raise ToolDefinitionError( diff --git a/arcade/tests/tool/test_create_tool_definition_errors.py b/arcade/tests/tool/test_create_tool_definition_errors.py index fa40d712..5e6d10bf 100644 --- a/arcade/tests/tool/test_create_tool_definition_errors.py +++ b/arcade/tests/tool/test_create_tool_definition_errors.py @@ -1,3 +1,5 @@ +from typing import Annotated + import pytest from arcade.core.catalog import ToolCatalog @@ -41,6 +43,13 @@ def func_with_multiple_context_params(context: ToolContext, context2: ToolContex pass +@tool(desc="A function with an invalid renamed parameter") +def func_with_invalid_renamed_param( + param1: Annotated[str, "invalid-param-name", "The first parameter"], +): + pass + + @tool( desc="A function with a required secret with a missing key (illegal)", requires_secrets=[""], @@ -95,6 +104,11 @@ def func_with_secret_requirement_invalid_type(): ToolDefinitionError, id=func_with_multiple_context_params.__name__, ), + pytest.param( + func_with_invalid_renamed_param, + ToolDefinitionError, + id=func_with_invalid_renamed_param.__name__, + ), pytest.param( func_with_missing_secret_key, ToolDefinitionError,