{"record":{"id":"1670a1be2506161d","repo":"crewAIInc/crewAI","slug":"failed-to-download-template-e","errorCode":null,"errorMessage":"Failed to download template: {e}","messagePattern":"Failed to download template: (.+?)","errorType":"console","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"lib/cli/src/crewai_cli/remote_template/main.py","lineNumber":214,"sourceCode":"\n        templates = self._fetch_templates()\n        template_names = {t[\"name\"] for t in templates}\n\n        for candidate in candidates:\n            if candidate in template_names:\n                return candidate\n\n        return None\n\n    def _download_zip(self, repo_name: str) -> bytes:\n        \"\"\"Download the default branch zipball for a repo.\"\"\"\n        url = f\"{GITHUB_API_BASE}/repos/{GITHUB_ORG}/{repo_name}/zipball\"\n        try:\n            response = httpx.get(url, follow_redirects=True, timeout=60)\n            response.raise_for_status()\n        except httpx.HTTPError as e:\n            click.secho(f\"Failed to download template: {e}\", fg=\"red\")\n            raise SystemExit(1) from e\n\n        return response.content\n\n    def _extract_zip(self, zip_bytes: bytes, dest: str) -> None:\n        \"\"\"Extract a GitHub zipball into dest, stripping the top-level directory.\"\"\"\n        with zipfile.ZipFile(io.BytesIO(zip_bytes)) as zf:\n            # GitHub zipballs have a single top-level dir like 'crewAIInc-fde-template_xxx-<sha>/'\n            members = zf.namelist()\n            if not members:\n                click.secho(\"Downloaded archive is empty.\", fg=\"red\")\n                raise SystemExit(1)\n\n            top_dir = members[0].split(\"/\")[0] + \"/\"\n\n            os.makedirs(dest, exist_ok=True)\n\n            for member in members:\n                if member == top_dir or not member.startswith(top_dir):","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/cli/src/crewai_cli/remote_template/main.py#L196-L232","documentation":"Raised by RemoteTemplateManager._download_zip() when downloading the zipball of a template repo (`{GITHUB_API_BASE}/repos/{GITHUB_ORG}/{repo_name}/zipball`, 60s timeout, redirects followed) fails with any httpx.HTTPError. The CLI aborts the `crewai template add` operation in red and exits 1; nothing is written to disk because download happens before extraction.","triggerScenarios":"GET of the zipball endpoint raising: connection reset/timeout for large repos on slow links (60s exceeded), 404 if the repo was deleted between list and add, 403/429 rate limiting, or a proxy stripping the redirect to codeload.github.com (follow_redirects=True requires the redirect to succeed).","commonSituations":"Slow networks downloading large templates; GitHub rate limits hit because each add re-lists repos then downloads; corporate SSL-inspecting proxies with untrusted CAs causing TLS errors; template removed upstream mid-session.","solutions":["Retry the command — most zipball failures are transient network/TLS issues.","If the message shows 404, re-run `crewai template list` to confirm the template still exists.","Configure proxy/CA trust (HTTPS_PROXY, SSL_CERT_FILE) in proxy environments.","Pre-download the zip manually from https://github.com/crewAIInc/<repo>/archive/refs/heads/main.zip as a workaround and unzip it yourself."],"exampleFix":"# before\n$ crewai template add template_deep_research\n# Failed to download template: Read timed out. (read timeout=60)\n\n# after\n$ crewai template add template_deep_research  # retry on a stable link, or:\n$ curl -L -o t.zip https://github.com/crewAIInc/template_deep_research/archive/refs/heads/main.zip && unzip t.zip","handlingStrategy":"retry","validationCode":"import httpx\n\nrepo = \"template_deep_research\"\nprobe = httpx.head(\n    f\"https://api.github.com/repos/crewAIInc/{repo}/zipball\",\n    follow_redirects=True,\n    timeout=15,\n)\nprobe.raise_for_status()  # confirms reachability + repo exists before the CLI run","typeGuard":null,"tryCatchPattern":"import time\n\nfor attempt in range(3):\n    try:\n        add_template(\"template_deep_research\")\n        break\n    except SystemExit:\n        time.sleep(3 * (attempt + 1))  # transient TLS/timeout: back off\nelse:\n    raise SystemExit(\"template download failed after retries\")","preventionTips":["Retry downloads on flaky links rather than switching templates — the failure is usually transient.","Set SSL_CERT_FILE/HTTPS_PROXY in TLS-intercepting environments before downloading.","Keep a manually downloaded zip as a fallback source for critical templates."],"tags":["network","httpx","download","template","timeout"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}