{"record":{"id":"5925373f2aa6b141","repo":"crewAIInc/crewAI","slug":"project-name-name-would-generate-invalid-pytho","errorCode":null,"errorMessage":"Project name '{name}' would generate invalid Python module name '{folder_name}'","messagePattern":"Project name '(.+?)' would generate invalid Python module name '(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/cli/src/crewai_cli/create_crew.py","lineNumber":81,"sourceCode":"        )\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\n    if not folder_name.isidentifier():\n        raise ValueError(\n            f\"Project name '{name}' would generate invalid Python module name '{folder_name}'\"\n        )\n\n    reserved_names = get_reserved_script_names()\n    if folder_name in reserved_names:\n        raise ValueError(\n            f\"Project name '{name}' would generate folder name '{folder_name}' which is reserved. \"\n            f\"Reserved names are: {', '.join(sorted(reserved_names))}. \"\n            \"Please choose a different name.\"\n        )\n\n    class_name = name.replace(\"_\", \" \").replace(\"-\", \" \").title().replace(\" \", \"\")\n\n    class_name = re.sub(r\"[^a-zA-Z0-9_]\", \"\", class_name)\n\n    if not class_name:\n        raise ValueError(\n            f\"Project name '{name}' contains no valid characters for a Python class name\"","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/cli/src/crewai_cli/create_crew.py#L63-L99","documentation":"Printed by PlusAPIMixin._validate_response when the CrewAI+ / Enterprise API returns a body that is not valid JSON (response.json() raises JSONDecodeError/ValueError). The CLI prints the status code and raw body, then raises SystemExit, aborting the deploy/plus command. Note the message itself contains a doubled 'failed' — it is cosmetic in the source.","triggerScenarios":"Any Plus API call whose response is HTML (auth proxy error page, 502 gateway page), plain text, or empty while claiming JSON — e.g. token expired so an SSO gateway returns an HTML redirect page, or the API endpoint is fronted by a proxy that returns a non-JSON error (command.py:53-63).","commonSituations":"Expired CrewAI+ session token causing an identity proxy to return HTML; transient gateway 502/503 with HTML body; corporate proxy intercepting the request; region/outage serving a maintenance page; CLI version pointing at a changed API route.","solutions":["Read the printed status code and raw response body in the CLI output — they identify the intercepting layer (gateway, SSO, proxy)","If the body is a login/redirect page, run 'crewai login' again to refresh the token","Retry after confirming the CrewAI+ service status if a 502/503 maintenance page is shown","Update the CLI (pip install -U crewai) in case API routes changed between CLI and server versions"],"exampleFix":"// before\nStatus Code: 502\nResponse:\n<html>Bad Gateway</html>   // proxy/gateway returned non-JSON\n\n// after (after service recovered / re-login)\nStatus Code: 200\nResponse parsed as JSON; command proceeds","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"# In code driving the Plus API directly:\nimport httpx\n\nr = await client.post(url, ...)\ntry:\n    payload = r.json()\nexcept (ValueError, httpx.DecodingError):\n    # non-JSON body: gateway/SSO interception — surface status + snippet\n    raise UpstreamNotJsonError(r.status_code, r.text[:200]) from None","preventionTips":["Check the HTTP status and Content-Type before assuming JSON: gate on response.headers.get('content-type', '').startswith('application/json')","Keep the CLI and CrewAI+ account/session in sync; re-login on HTML responses that look like SSO pages","Script around SystemExit: CLI aborts via raise SystemExit, so subprocess wrappers should treat non-zero exit plus this message as an upstream-format issue","Capture the printed status code and raw body in CI logs — they identify whether the proxy, gateway, or IdP intercepted the call"],"tags":["cli","crewai-plus","json","gateway","http-error"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}