{"record":{"id":"020c1f8b34bf4786","repo":"microsoft/autogen","slug":"invalid-name-name-only-letters-numbers-a-020c1f","errorCode":null,"errorMessage":"Invalid name: {name}. Only letters, numbers, '_' and '-' are allowed.","messagePattern":"Invalid name: (.+?)\\. Only letters, numbers, '_' and '-' are allowed\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py","lineNumber":77,"sourceCode":"\n\ndef normalize_name(name: str) -> str:\n    \"\"\"\n    LLMs sometimes ask functions while ignoring their own format requirements, this function should be used to replace invalid characters with \"_\".\n\n    Prefer _assert_valid_name for validating user configuration or input\n    \"\"\"\n    return re.sub(r\"[^a-zA-Z0-9_-]\", \"_\", name)[:64]\n\n\ndef assert_valid_name(name: str) -> str:\n    \"\"\"\n    Ensure that configured names are valid, raises ValueError if not.\n\n    For munging LLM responses use _normalize_name to ensure LLM specified names don't break the API.\n    \"\"\"\n    if not re.match(r\"^[a-zA-Z0-9_-]+$\", name):\n        raise ValueError(f\"Invalid name: {name}. Only letters, numbers, '_' and '-' are allowed.\")\n    if len(name) > 64:\n        raise ValueError(f\"Invalid name: {name}. Name must be less than 64 characters.\")\n    return name\n\n\ndef convert_tools(\n    tools: Sequence[Tool | ToolSchema],\n) -> List[ChatCompletionTool]:\n    result: List[ChatCompletionTool] = []\n    for tool in tools:\n        if isinstance(tool, Tool):\n            tool_schema = tool.schema\n        else:\n            assert isinstance(tool, dict)\n            tool_schema = tool\n\n        result.append(\n            ChatCompletionTool(","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/microsoft/autogen/blob/027ecf0a379bcc1d09956d46d12d44a3ad9cee14/python/packages/autogen-ext/src/autogen_ext/models/llama_cpp/_llama_cpp_completion_client.py#L59-L95","documentation":"Raised by assert_valid_name in autogen_ext.models.llama_cpp._llama_cpp_completion_client when a name contains characters outside [a-zA-Z0-9_-] (regex ^[a-zA-Z0-9_-]+$). llama-cpp server tooling requires this name charset, so the local client validates message sources / tool names before conversion; _normalize_name is the munging counterpart for LLM-generated names.","triggerScenarios":"Passing a tool with a name like 'get.weather' or a message source with spaces/unicode to LlamaCppChatCompletionClient.create()/create_stream(); LLM hallucinating a function name with dots or parentheses (should be normalized, not asserted).","commonSituations":"Tool schemas authored with dotted names; agent names copied from display labels; multi-agent runs where the same UserMessage sources used elsewhere are reused against llama.cpp.","solutions":["Rename tools/agents to only letters, digits, '_' and '-'","For LLM-emitted names, sanitize with the module's _normalize_name before use","Validate names once at registration time, not per request"],"exampleFix":"# before\ntool = Tool(name=\"get.weather\", description=\"...\", run=fn)\n\n# after\ntool = Tool(name=\"get_weather\", description=\"...\", run=fn)","handlingStrategy":"validation","validationCode":"import re\n\ndef tool_name_ok(name: str) -> bool:\n    return bool(re.fullmatch(r\"[a-zA-Z0-9_-]+\", name)) and len(name) <= 64","typeGuard":"import re\n\ndef is_valid_tool_name(name: str) -> bool:\n    return re.fullmatch(r\"[a-zA-Z0-9_-]{1,64}\", name) is not None","tryCatchPattern":null,"preventionTips":["Name tools with letters/digits/underscore/hyphen only","Normalize LLM-proposed function names before executing them","Validate all tool names at registration time"],"tags":["llama-cpp","name-validation","tools","regex"],"backgroundTag":null,"analyzedSha":"027ecf0a379bcc1d09956d46d12d44a3ad9cee14","analyzedAt":"2026-08-15T03:38:00.719Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}