{"record":{"id":"8c74faa64d485b85","repo":"crewAIInc/crewAI","slug":"project-name-name-contains-no-valid-characters","errorCode":null,"errorMessage":"Project name '{name}' contains no valid characters for a Python module name","messagePattern":"Project name '(.+?)' contains no valid characters for a Python module name","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/cli/src/crewai_cli/create_crew.py","lineNumber":61,"sourceCode":"    return script_names\n\n\ndef create_folder_structure(\n    name: str, parent_folder: str | None = None\n) -> tuple[Path, str, str]:\n    import keyword\n    import re\n\n    name = name.rstrip(\"/\")\n\n    if not name.strip():\n        raise ValueError(\"Project name cannot be empty or contain only whitespace\")\n\n    folder_name = name.replace(\" \", \"_\").replace(\"-\", \"_\").lower()\n    folder_name = re.sub(r\"[^a-zA-Z0-9_]\", \"\", folder_name)\n\n    if re.match(r\"^[^a-zA-Z0-9_-]+\", name):\n        raise ValueError(\n            f\"Project name '{name}' contains no valid characters for a Python module name\"\n        )\n\n    if not folder_name:\n        raise ValueError(\n            f\"Project name '{name}' contains no valid characters for a Python module name\"\n        )\n\n    if folder_name[0].isdigit():\n        raise ValueError(\n            f\"Project name '{name}' would generate folder name '{folder_name}' which cannot start with a digit (invalid Python module name)\"\n        )\n\n    if keyword.iskeyword(folder_name):\n        raise ValueError(\n            f\"Project name '{name}' would generate folder name '{folder_name}' which is a reserved Python keyword\"\n        )\n","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/cli/src/crewai_cli/create_crew.py#L43-L79","documentation":"Raised by validate_auth_against_agent_card (as A2AClientHTTPError 401) when the client's auth object is the wrong class for what the remote agent's AgentCard security schemes declare. The client-side preflight maps AgentCard security scheme types to allowed ClientAuthScheme classes (_SCHEME_AUTH_MAPPING, _HTTP_SCHEME_MAPPING) and rejects mismatches before any network call.","triggerScenarios":"Fetching an AgentCard whose security_schemes declare e.g. APIKeySecurityScheme or an HTTPAuthSecurityScheme(scheme='bearer') and then passing auth=BearerTokenAuth(...) (or vice versa) to the A2A client invoke. _raise_auth_mismatch formats this exact message naming the required class(es) and the provided class (utils.py:89-115).","commonSituations":"Server switched from API-key to OAuth2 between releases; developer copies sample code that uses BearerTokenAuth against an agent that requires APIKeyAuth; multiple security schemes on one card and the developer picks the wrong one to satisfy.","solutions":["Fetch the AgentCard and read agent_card.security_schemes to see exactly which scheme(s) the first security requirement names","Construct the matching client auth class: APIKeySecurityScheme -> APIKeyAuth, OAuth2SecurityScheme -> OAuth2ClientAuth, HTTPAuth 'basic' -> BasicAuth, HTTPAuth 'bearer' -> BearerTokenAuth","If the card lists alternative schemes (list in security[0]), any one of the allowed classes satisfies the check","After upgrading the remote agent, re-fetch the AgentCard instead of reusing a cached one, since requirements may have changed"],"exampleFix":"# before\nclient = A2AClient(agent_card)\nawait client.invoke(..., auth=BearerTokenAuth(token=tok))  # card requires APIKeyAuth\n\n# after\nclient = A2AClient(agent_card)\nawait client.invoke(..., auth=APIKeyAuth(api_key=os.environ['A2A_API_KEY']))","handlingStrategy":"validation","validationCode":"from crewai.a2a.auth.utils import validate_auth_against_agent_card\n\nvalidate_auth_against_agent_card(agent_card, auth)  # raises A2AClientHTTPError early with a precise message\n# call this right after fetching the card, before building the full request","typeGuard":"from crewai.a2a.auth.schemes import (\n    APIKeyAuth, BearerTokenAuth, BasicAuth, OAuth2ClientAuth, ClientAuthScheme,\n)\nfrom crewai.a2a.auth.utils import validate_auth_against_agent_card\n\ndef auth_matches_card(auth: ClientAuthScheme, card) -> bool:\n    try:\n        validate_auth_against_agent_card(card, auth)\n        return True\n    except Exception:\n        return False","tryCatchPattern":"from crewai.a2a.auth.errors import A2AClientHTTPError\nfrom crewai.a2a.auth.utils import validate_auth_against_agent_card\n\ntry:\n    validate_auth_against_agent_card(card, auth)\nexcept A2AClientHTTPError as e:\n    if e.code == 401 and \"requires\" in str(e):\n        auth = pick_auth_for_card(card)  # construct the class named in the message\n    else:\n        raise","preventionTips":["Always run validate_auth_against_agent_card immediately after fetching the AgentCard to fail before doing request work","Derive the auth class from the card itself (switch on security_schemes types) instead of hardcoding one","Re-fetch the AgentCard on every session start; never persist it across deployments","Write a unit test per supported scheme (apiKey, http/basic, http/bearer, oauth2) asserting your auth factory matches"],"tags":["a2a","authentication","agent-card","client","http-401"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}