{"record":{"id":"2da9dfe1b03dca7b","repo":"affaan-m/ECC","slug":"download-exceeds-maximum-allowed-size","errorCode":null,"errorMessage":"download exceeds maximum allowed size","messagePattern":"download exceeds maximum allowed size","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/falapi.py","lineNumber":712,"sourceCode":"    opener = urllib.request.build_opener(_SafeRedirect())\n    temporary = None\n    try:\n        with opener.open(req, timeout=300) as resp:\n            declared = getattr(resp, \"headers\", {}).get(\"Content-Length\")\n            expected = int(declared) if declared is not None else None\n            if expected is not None and not 0 <= expected <= MAX_DOWNLOAD_BYTES:\n                raise FalError(\"download declares an invalid or excessive size\")\n            with tempfile.NamedTemporaryFile(dir=dest.parent, prefix=\".taste-download-\",\n                                             delete=False) as fh:\n                temporary = Path(fh.name)\n                total = 0\n                while True:\n                    chunk = resp.read(min(1024 * 1024, MAX_DOWNLOAD_BYTES - total + 1))\n                    if not chunk:\n                        break\n                    total += len(chunk)\n                    if total > MAX_DOWNLOAD_BYTES:\n                        raise FalError(\"download exceeds maximum allowed size\")\n                    fh.write(chunk)\n                if expected is not None and total != expected:\n                    raise FalError(\"download length does not match declared size\")\n        os.replace(temporary, dest)\n        temporary = None\n    except FalError:\n        raise\n    except Exception:\n        raise FalError(\"download failed; existing destination preserved\") from None\n    finally:\n        if temporary is not None:\n            temporary.unlink(missing_ok=True)\n    return dest\n\n\n# ---------------------------------------------------------------------------\n# dry-run stubs\n# ---------------------------------------------------------------------------","sourceCodeStart":694,"sourceCodeEnd":730,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/falapi.py#L694-L730","documentation":"FalError raised during the streaming read loop of download() when the bytes actually received exceed MAX_DOWNLOAD_BYTES, even if no (or an understated) Content-Length was declared. This is the enforced hard cap on download size, preventing unbounded writes to disk from a malicious or misbehaving server.","triggerScenarios":"Downloading a file whose streamed body exceeds MAX_DOWNLOAD_BYTES while Content-Length is absent or lies (chunked transfer, compressed responses, misconfigured proxies).","commonSituations":"Chunked-encoding responses with no Content-Length that turn out to be huge; a redirect to a large asset; corrupted provider responses serving much more data than declared.","solutions":["Check the asset size before download (HEAD request) and avoid oversized files","Download genuinely large assets with a different tool outside this library's cap","If you control the generation parameters, reduce output resolution/duration so the artifact fits under the cap","Deliberately raise MAX_DOWNLOAD_BYTES in the module if your workflow legitimately needs bigger files"],"exampleFix":"// before\ndownload(video_url, \"output.mp4\")  # 4K, ~3GB\n// after\nimport urllib.request\nsize = int(urllib.request.urlopen(urllib.request.Request(video_url, method=\"HEAD\")).headers.get(\"Content-Length\", 0))\nassert size <= MAX_DOWNLOAD_BYTES, f\"{size} bytes exceeds cap\"\ndownload(video_url, \"output.mp4\")","handlingStrategy":"try-catch","validationCode":"import urllib.request\nreq = urllib.request.Request(url, method=\"HEAD\")\nwith urllib.request.urlopen(req) as r:\n    clen = r.headers.get(\"Content-Length\")\nif clen is not None and int(clen) > MAX_DOWNLOAD_BYTES:\n    raise SystemExit(\"skip: streamed asset would exceed download cap\")","typeGuard":null,"tryCatchPattern":"try:\n    download(url, dest)\nexcept FalError as e:\n    if \"exceeds maximum\" in str(e):\n        logging.error(\"streamed download exceeded cap; partial file cleaned up for %s\", safe_url(url))\n    raise","preventionTips":["HEAD-check size first, especially for chunked responses without Content-Length","Cap generation duration/resolution so artifacts stay under the size limit","Use an alternative downloader for legitimately oversized assets","Remember the temp file is cleaned up on failure — never assume partial output exists"],"tags":["download","http","size-limit"],"backgroundTag":"file-size-limit-exceeded","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}