affaan-m/ECC · error · FalError
download exceeds maximum allowed size
Error message
download exceeds maximum allowed size
What it means
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.
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
Example fix
// before
download(video_url, "output.mp4") # 4K, ~3GB
// after
import urllib.request
size = int(urllib.request.urlopen(urllib.request.Request(video_url, method="HEAD")).headers.get("Content-Length", 0))
assert size <= MAX_DOWNLOAD_BYTES, f"{size} bytes exceeds cap"
download(video_url, "output.mp4") Defensive patterns
Strategy: try-catch
Validate before calling
import urllib.request
req = urllib.request.Request(url, method="HEAD")
with urllib.request.urlopen(req) as r:
clen = r.headers.get("Content-Length")
if clen is not None and int(clen) > MAX_DOWNLOAD_BYTES:
raise SystemExit("skip: streamed asset would exceed download cap") Try / catch
try:
download(url, dest)
except FalError as e:
if "exceeds maximum" in str(e):
logging.error("streamed download exceeded cap; partial file cleaned up for %s", safe_url(url))
raise Prevention
- 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
When it happens
Trigger: Downloading a file whose streamed body exceeds MAX_DOWNLOAD_BYTES while Content-Length is absent or lies (chunked transfer, compressed responses, misconfigured proxies).
Common situations: 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.
Understand the failure class
Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.
Related errors
- download declares an invalid or excessive size
- download declares an invalid or excessive size
- download exceeds maximum allowed size
- download exceeds maximum allowed size
- download length does not match declared size
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/2da9dfe1b03dca7b.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-application/scripts/falapi.py:712
opener = urllib.request.build_opener(_SafeRedirect())
temporary = None
try:
with opener.open(req, timeout=300) as resp:
declared = getattr(resp, "headers", {}).get("Content-Length")
expected = int(declared) if declared is not None else None
if expected is not None and not 0 <= expected <= MAX_DOWNLOAD_BYTES:
raise FalError("download declares an invalid or excessive size")
with tempfile.NamedTemporaryFile(dir=dest.parent, prefix=".taste-download-",
delete=False) as fh:
temporary = Path(fh.name)
total = 0
while True:
chunk = resp.read(min(1024 * 1024, MAX_DOWNLOAD_BYTES - total + 1))
if not chunk:
break
total += len(chunk)
if total > MAX_DOWNLOAD_BYTES:
raise FalError("download exceeds maximum allowed size")
fh.write(chunk)
if expected is not None and total != expected:
raise FalError("download length does not match declared size")
os.replace(temporary, dest)
temporary = None
except FalError:
raise
except Exception:
raise FalError("download failed; existing destination preserved") from None
finally:
if temporary is not None:
temporary.unlink(missing_ok=True)
return dest
# ---------------------------------------------------------------------------
# dry-run stubs
# ---------------------------------------------------------------------------View on GitHub (pinned to 8321021c54)