affaan-m/ECC · error · FalError
download failed; existing destination preserved
Error message
download failed; existing destination preserved
What it means
download() wraps the whole transfer in a generic except that converts any non-FalError exception (socket errors, TLS failures, HTTPError, OSError) into a single FalError with a user-safe message. The original cause is intentionally discarded (from None) and the pre-existing destination file is left untouched because the temp file was never os.replace()'d.
Solutions
- Check network connectivity and that fal.media is reachable (curl -I the URL)
- Inspect whether the destination directory exists and is writable, since temp files are created there
- Catch FalError and retry with backoff for transient server/network issues
- Temporarily instrument or re-raise to see the underlying cause, since the message hides it
Example fix
// before
FalError: download failed; existing destination preserved
// after
try:
download(url, dest)
except FalError:
if not dest.exists():
raise RuntimeError(f"download failed and no fallback at {dest}") Defensive patterns
Strategy: try-catch
Validate before calling
import socket
socket.create_connection(("fal.media", 443), timeout=5) # pre-flight reachability Try / catch
try:
download(url, dest)
except FalError as e:
if not dest.exists():
raise RuntimeError(f"no prior asset at {dest}: {e}") from e
log.info("using existing %s after failed refresh", dest) Prevention
- Check network/egress rules in CI before runs
- Ensure the destination directory exists and is writable (temp file lives there)
- Keep a previously downloaded copy so a failed refresh is non-fatal
When it happens
Trigger: DNS resolution failure, connection refused/reset, TLS handshake error, HTTP 4xx/5xx from the server, timeout after 300s, or local filesystem error creating/writing the temp file.
Common situations: No internet or blocked egress in CI; fal.media temporarily down or rate-limiting; corporate proxy breaking HTTPS; destination directory not writable.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- download failed; existing destination preserved
- cannot open
- cannot open video
- cannot read overlay image
- cannot read plate
AI-assisted analysis of affaan-m/ECC@8321021c54 (2026-09-16).
Data as JSON: /api/errors/1c429983a5446d74.
Report an issue: GitHub.
Appendix: source
Thrown at skills/taste-distillation/scripts/taste/falapi.py:721
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
# ---------------------------------------------------------------------------
def _digest(*parts: Any) -> str:
h = hashlib.sha256("|".join(str(p) for p in parts).encode("utf-8"))
return h.hexdigest()[:12]
def _stub_from_schema(schema: dict) -> dict:
"""Build a stub object with the same keys and types as ``schema``."""View on GitHub (pinned to 8321021c54)