{"record":{"id":"64f19f324f8fcde0","repo":"affaan-m/ECC","slug":"download-declares-an-invalid-or-excessive-size","errorCode":null,"errorMessage":"download declares an invalid or excessive size","messagePattern":"download declares an invalid or excessive size","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-application/scripts/falapi.py","lineNumber":701,"sourceCode":"    if is_dry_run():\n        dest.parent.mkdir(parents=True, exist_ok=True)\n        dest.write_bytes(b\"taste-forge dry-run placeholder\\n\")\n        log.info(\"[dry-run] would download from %s\", safe_url(url))\n        return dest\n\n    require_live()\n    _validate_download_url(url)\n    dest.parent.mkdir(parents=True, exist_ok=True)\n    log.info(\"downloading from %s\", safe_url(url))\n    req = urllib.request.Request(url, headers={\"User-Agent\": \"taste-forge\"})\n    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","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-application/scripts/falapi.py#L683-L719","documentation":"FalError raised inside download() when the HTTP response's Content-Length header is present but not an integer in the range 0..MAX_DOWNLOAD_BYTES. This catches servers declaring a corrupt (negative/non-numeric parse failure handled separately) or oversized body so the transfer is aborted before reading megabytes of data.","triggerScenarios":"Downloading a file whose server returns a Content-Length header larger than MAX_DOWNLOAD_BYTES (e.g. a multi-gigabyte video); a malformed Content-Length value that int() cannot parse (raises before this check) or a negative value.","commonSituations":"Pointing download() at a very large asset that exceeds the library's size policy; a proxy injecting a bogus Content-Length header; misusing download() for files it was not designed for (huge raw footage).","solutions":["Check the file size via HEAD request before calling download() and skip files above MAX_DOWNLOAD_BYTES","Download oversized assets outside this library (e.g. plain urllib/curl) if you genuinely need them","If a proxy is mangling headers, bypass it or fix its Content-Length handling","Increase MAX_DOWNLOAD_BYTES in the module only deliberately, understanding the memory/disk tradeoff"],"exampleFix":"// before\ndownload(huge_video_url, out)\n// after\nreq = urllib.request.Request(huge_video_url, method=\"HEAD\")\nsize = int(urllib.request.urlopen(req).headers[\"Content-Length\"])\nif size > MAX_DOWNLOAD_BYTES:\n    raise SystemExit(f\"asset too large: {size} bytes\")\ndownload(huge_video_url, out)","handlingStrategy":"validation","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(f\"asset too large to download: {clen} bytes\")","typeGuard":null,"tryCatchPattern":"try:\n    download(url, dest)\nexcept FalError as e:\n    if \"excessive size\" in str(e):\n        logging.error(\"download declared size exceeds cap for %s\", safe_url(url))\n    raise","preventionTips":["HEAD-check Content-Length before large downloads","Skip assets above MAX_DOWNLOAD_BYTES in pipeline planning","Watch for proxies mangling Content-Length headers","Keep generation outputs within the size budget (resolution/duration limits)"],"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"}