iflytek/astron-agent · error · RemoteResourcePolicyError
Remote resource returned HTTP
Error message
Remote resource returned HTTP {response.status} What it means
In _download_resource, any response status outside 200–299 (redirects are NOT followed, allow_redirects=False) raises RemoteResourcePolicyError with the status code embedded in the message. This converts HTTP-level failures and redirects into policy rejections so callers cannot be tricked into following redirects to internal hosts.
Solutions
- Read the HTTP status from the message and address it: fix the object key for 404, refresh presigned credentials for 403.
- Resolve the redirect yourself: fetch the final public http(s) URL and pass that directly — the library will not follow redirects by design (SSRF protection).
- Retry only on transient 5xx, ideally with backoff; do not retry 4xx.
Example fix
// before
await fetch_public_resource("https://cdn.example.com/file") // server 302s elsewhere
// after
await fetch_public_resource("https://origin.example.com/actual/file") // final, non-redirecting URL Defensive patterns
Strategy: validation
Validate before calling
# resolve redirects yourself before calling
import aiohttp
async def final_url(url):
async with aiohttp.ClientSession() as s:
async with s.head(url, allow_redirects=True) as r:
return str(r.url) Try / catch
try:
data = await fetch_public_resource(url)
except HTTPClientException as e:
if "HTTP 3" in str(e):
url = await resolve_redirect(url); data = await fetch_public_resource(url) Prevention
- Use direct, non-redirecting object URLs
- Refresh presigned URLs before they expire (403)
- Verify object keys exist (404) before download
When it happens
Trigger: The remote server replies 3xx (301/302/307 redirect), 403 (private object), 404 (missing file), 5xx, etc. on a GET of the caller-supplied URL.
Common situations: Object storage returning 302 to a presigned CDN URL; expired presigned S3 URL giving 403; typo'd object key giving 404; rate-limited or erroring upstream giving 5xx.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- HTTPClientError
- Remote resource address is unsafe
- KNOWLEDGE_REQUEST_ERROR
- MCP_REQUEST_ERROR
- sandbox-exec failed: HTTP
AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12).
Data as JSON: /api/errors/f1dcd7e6d1188cce.
Report an issue: GitHub.
Appendix: source
Thrown at core/plugin/aitools/common/clients/safe_download.py:140
CodeEnums.HTTPClientError,
extra_message="Remote resource download failed",
) from exc
async def _download_resource(
url: str,
connector: aiohttp.TCPConnector,
timeout: aiohttp.ClientTimeout,
max_bytes: int,
) -> bytes:
async with aiohttp.ClientSession(
connector=connector,
timeout=timeout,
trust_env=False,
) as session:
async with session.get(url, allow_redirects=False) as response:
if not 200 <= response.status < 300:
raise RemoteResourcePolicyError(
f"Remote resource returned HTTP {response.status}"
)
return await _read_bounded_response(response, max_bytes)
async def _read_bounded_response(
response: aiohttp.ClientResponse,
max_bytes: int,
) -> bytes:
content_length = response.content_length
if content_length is not None and content_length > max_bytes:
raise RemoteResourcePolicyError("Remote resource is too large")
content = bytearray()
async for chunk in response.content.iter_chunked(_DOWNLOAD_CHUNK_SIZE):
if len(content) + len(chunk) > max_bytes:
raise RemoteResourcePolicyError("Remote resource is too large")
content.extend(chunk)View on GitHub (pinned to 5e758547a8)