{"record":{"id":"1c429983a5446d74","repo":"affaan-m/ECC","slug":"download-failed-existing-destination-preserved-1c4299","errorCode":null,"errorMessage":"download failed; existing destination preserved","messagePattern":"download failed; existing destination preserved","errorType":"exception","errorClass":"FalError","httpStatus":null,"severity":"error","filePath":"skills/taste-distillation/scripts/taste/falapi.py","lineNumber":721,"sourceCode":"                                             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# ---------------------------------------------------------------------------\n\n\ndef _digest(*parts: Any) -> str:\n    h = hashlib.sha256(\"|\".join(str(p) for p in parts).encode(\"utf-8\"))\n    return h.hexdigest()[:12]\n\n\ndef _stub_from_schema(schema: dict) -> dict:\n    \"\"\"Build a stub object with the same keys and types as ``schema``.\"\"\"","sourceCodeStart":703,"sourceCodeEnd":739,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/skills/taste-distillation/scripts/taste/falapi.py#L703-L739","documentation":"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.","triggerScenarios":"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.","commonSituations":"No internet or blocked egress in CI; fal.media temporarily down or rate-limiting; corporate proxy breaking HTTPS; destination directory not writable.","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"],"exampleFix":"// before\nFalError: download failed; existing destination preserved\n// after\ntry:\n    download(url, dest)\nexcept FalError:\n    if not dest.exists():\n        raise RuntimeError(f\"download failed and no fallback at {dest}\")","handlingStrategy":"try-catch","validationCode":"import socket\nsocket.create_connection((\"fal.media\", 443), timeout=5)  # pre-flight reachability","typeGuard":null,"tryCatchPattern":"try:\n    download(url, dest)\nexcept FalError as e:\n    if not dest.exists():\n        raise RuntimeError(f\"no prior asset at {dest}: {e}\") from e\n    log.info(\"using existing %s after failed refresh\", dest)","preventionTips":["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"],"tags":["network","file-io","error-wrapping"],"backgroundTag":"http-request-failed","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"}