iflytek/astron-agent · error · RemoteResourcePolicyError

Remote resource path is invalid

Error message

Remote resource path is invalid

What it means

RemoteResourcePolicyError raised by _decoded_path when the URL path cannot be safely decoded: it contains a malformed percent-escape (e.g. '%zz', a bare '%') or its percent-decoded bytes are not valid UTF-8. Used only by _is_configured_storage_url to compare the candidate path against configured S3 bucket prefixes, so a broken path also means private-storage authorization silently fails.

Solutions

  1. Percent-encode the path correctly: urllib.parse.quote(path, safe='/') with a known UTF-8 source string
  2. Re-upload or re-name the object with a UTF-8-safe filename and regenerate the URL
  3. Fix double-encoding in the URL-producing code (don't quote an already-quoted string)

Example fix

// before
url = f"https://s3.example.com/my-bucket/{filename}"  # filename = '报告%进行中.pdf' (partially encoded)
// after
from urllib.parse import quote
url = f"https://s3.example.com/my-bucket/{quote(filename, safe='')}"
Defensive patterns

Strategy: validation

Validate before calling

import re
from urllib.parse import unquote_to_bytes
INVALID_ESCAPE = re.compile(r"%(?![0-9a-fA-F]{2})")
def path_decodes_cleanly(url: str) -> bool:
    raw = url.split("?", 1)[0]
    if INVALID_ESCAPE.search(raw):
        return False
    try:
        raw_path = raw.split("://", 1)[-1].split("/", 1)
        path = "/" + raw_path[1] if len(raw_path) > 1 else "/"
        unquote_to_bytes(path).decode("utf-8")
    except (UnicodeDecodeError, ValueError):
        return False
    return True

Try / catch

try:
    data = await fetch_public_resource(url)
except HTTPClientException as e:
    if "path is invalid" in str(e):
        log.warning("Storage URL path has invalid percent-encoding or non-UTF-8 bytes")
    raise

Prevention

When it happens

Trigger: A candidate storage URL whose path contains invalid percent-encoding ('/my-bucket/file%.pdf') or percent-encoded bytes that don't form UTF-8 ('/my-bucket/%FF%FE.txt'), evaluated during private-storage authorization.

Common situations: Filenames uploaded with non-UTF-8 (e.g. GBK) encodings then blindly percent-encoded into URLs; double-encoding bugs producing stray '%' characters; copy-pasted URLs truncated mid-escape.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of iflytek/astron-agent@5e758547a8 (2026-09-12). Data as JSON: /api/errors/18b6b39fecfc3d7e. Report an issue: GitHub.

Appendix: source

Thrown at core/plugin/aitools/common/clients/safe_download.py:323

            required_prefix
        ):
            return True
    return False


def _effective_port(parsed: SplitResult) -> int:
    if parsed.port is not None:
        return parsed.port
    return 443 if parsed.scheme.lower() == "https" else 80


def _decoded_path(raw_path: str) -> str:
    try:
        if _INVALID_PERCENT_ESCAPE.search(raw_path):
            raise ValueError
        value = unquote_to_bytes(raw_path).decode("utf-8", errors="strict")
    except (UnicodeDecodeError, ValueError):
        raise RemoteResourcePolicyError("Remote resource path is invalid") from None
    if (
        not value.startswith("/")
        or "\\" in value
        or any(ord(character) < 0x20 or ord(character) == 0x7F for character in value)
        or any(segment in {".", ".."} for segment in value.split("/"))
    ):
        raise RemoteResourcePolicyError("Remote resource path is invalid")
    return value


def _canonical_address(address: IpAddress) -> IpAddress:
    if isinstance(address, ipaddress.IPv6Address) and address.ipv4_mapped:
        return address.ipv4_mapped
    return address


def _matches_any(address: IpAddress, networks: Tuple[IpNetwork, ...]) -> bool:
    candidates: Tuple[IpAddress, ...] = (address,)

View on GitHub (pinned to 5e758547a8)