{"record":{"id":"68b411a0688736a4","repo":"agentscope-ai/agentscope","slug":"failed-to-fetch-bytes-from-url-url-after-max","errorCode":null,"errorMessage":"Failed to fetch bytes from URL `{url}` after {max_retries} retries.","messagePattern":"Failed to fetch bytes from URL `(.+?)` after (.+?) retries\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/agentscope/_utils/_common.py","lineNumber":250,"sourceCode":"    import requests\n\n    for _ in range(max_retries):\n        try:\n            response = requests.get(url)\n            response.raise_for_status()\n            return response.content.decode(\"utf-8\")\n\n        except UnicodeDecodeError:\n            return base64.b64encode(response.content).decode(\"ascii\")\n\n        except Exception as e:\n            logger.info(\n                \"Failed to fetch bytes from URL %s. Error %s. Retrying...\",\n                url,\n                str(e),\n            )\n\n    raise RuntimeError(\n        f\"Failed to fetch bytes from URL `{url}` after {max_retries} retries.\",\n    )\n\n\ndef _map_text_to_uuid(text: str) -> str:\n    \"\"\"Map the given text to a deterministic UUID string.\n\n    Args:\n        text (`str`):\n            The input text to be mapped to a UUID.\n\n    Returns:\n        `str`:\n            A deterministic UUID string derived from the input text.\n    \"\"\"\n    return str(uuid.uuid3(uuid.NAMESPACE_DNS, text))\n\n","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/_utils/_common.py#L232-L268","documentation":"agentscope downloads remote resources (images, audio, files) referenced by URL via _get_bytes_from_web_url. It retries the HTTP request up to max_retries times and, if all attempts fail (connection error, timeout, non-success status), raises this RuntimeError naming the URL and retry count.","triggerScenarios":"Passing a URL block (e.g. an image or audio block with a URL) where the host is unreachable, returns 404/403/5xx, DNS fails, or the process has no network egress. Every retry must fail; transient failures usually succeed on retry.","commonSituations":"Offline or sandboxed environments without internet, expired/signed S3 URLs, hotlinking-protected URLs requiring headers, typos in URLs, corporate proxies not configured, or remote endpoints with transient 503s exceeding the retry budget.","solutions":["Verify the URL is reachable (curl -I <url>) from the same environment","If behind a proxy, set HTTP_PROXY/HTTPS_PROXY environment variables","Increase max_retries for flaky endpoints, or add your own retry/backoff around the call","If the resource is local, pass local file bytes instead of a URL; for authenticated resources, download with headers yourself and pass the bytes"],"exampleFix":"# before\nblock = ImageBlock(url=\"https://example.com/pic.png\")  # host unreachable\n\n# after\nimport requests\nresp = requests.get(\"https://example.com/pic.png\", headers={\"Authorization\": \"Bearer ...\"}, timeout=30)\nresp.raise_for_status()\nblock = ImageBlock(bytes=resp.content)  # pass bytes directly","handlingStrategy":"retry","validationCode":"import requests\n\ndef url_is_fetchable(url: str, timeout: float = 10.0) -> bool:\n    try:\n        r = requests.head(url, timeout=timeout, allow_redirects=True)\n        return r.status_code < 400\n    except requests.RequestException:\n        return False\n\nif not url_is_fetchable(url):\n    # serve local bytes or fail gracefully instead of letting the library raise","typeGuard":"from urllib.parse import urlparse\nfrom typing import TypeGuard\n\ndef is_http_url(v: str) -> TypeGuard[str]:\n    try:\n        p = urlparse(v)\n        return p.scheme in (\"http\", \"https\") and bool(p.netloc)\n    except ValueError:\n        return False","tryCatchPattern":"try:\n    block = ImageBlock(url=url)\n    ...  # downstream processing\nexcept RuntimeError as e:\n    if \"Failed to fetch bytes\" in str(e):\n        # exponential backoff retry, then fall back to local file\n        for attempt in range(5):\n            try:\n                break\n            except RuntimeError:\n                time.sleep(2 ** attempt)\n        else:\n            block = ImageBlock(bytes=local_fallback_bytes)\n    else:\n        raise","preventionTips":["Health-check remote URLs before embedding them in blocks","Configure proxy env vars in sandboxed environments","Cache downloaded assets locally and pass bytes on subsequent runs","Set generous timeouts and retries for flaky third-party hosts"],"tags":["network","http","download","retry","url"],"backgroundTag":"url-fetch-failed","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}