{"record":{"id":"53337e71edf1b6f0","repo":"affaan-m/ECC","slug":"download-declares-an-invalid-or-excessive-size-falapi","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/taste/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/taste/falapi.py#L683-L719","documentation":"download() reads the Content-Length header and rejects the response if the declared size is negative or larger than MAX_DOWNLOAD_BYTES. This prevents allocating/disk-filling downloads for oversized or malformed responses before any bytes are written.","triggerScenarios":"Server responds with Content-Length exceeding MAX_DOWNLOAD_BYTES (e.g. a huge video), or with a negative/undecodable value that int() accepts as out of bounds (negative sizes). Note: a non-integer Content-Length raises ValueError caught by the generic handler instead.","commonSituations":"Downloading a long rendered video that legitimately exceeds the configured MAX_DOWNLOAD_BYTES; a misbehaving/proxied server emitting a bogus Content-Length; attempting to download a full mesh sequence bundle rather than a single asset.","solutions":["Raise MAX_DOWNLOAD_BYTES in falapi.py to accommodate the asset you expect","Download the large asset with your own streaming HTTP client and your own size policy","Check the actual asset size (curl -sI) before downloading to see if the limit is the blocker","If the header is bogus, retry the download — a proxy may have corrupted the response"],"exampleFix":"# before\n# falapi.py\nMAX_DOWNLOAD_BYTES = 512 * 1024 * 1024\n# after\nMAX_DOWNLOAD_BYTES = 2 * 1024 * 1024 * 1024  # allow larger videos","handlingStrategy":"validation","validationCode":"import urllib.request\nreq = urllib.request.Request(url, method='HEAD')\nsize = int(urllib.request.urlopen(req).headers.get('Content-Length', 0))\nassert 0 <= size <= 512 * 1024 * 1024, 'asset exceeds download limit'","typeGuard":null,"tryCatchPattern":"try:\n    download(url, dest)\nexcept FalError:\n    # stream manually with your own cap\n    ...","preventionTips":["HEAD-check Content-Length before downloading large assets","Set MAX_DOWNLOAD_BYTES appropriately for your largest expected asset (long videos)","Keep an eye on the module's size constant when the library updates","Avoid pointing download at bundle/sequence files that can be very large"],"tags":["download","size-limit","http"],"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"}