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

  1. Read the HTTP status from the message and address it: fix the object key for 404, refresh presigned credentials for 403.
  2. 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).
  3. 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

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


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)