iflytek/astron-agent · error · OssServiceException

9010

9010

Error message

str(e)

What it means

OssServiceException (code 9010) wrapping any exception raised during the S3 upload_file flow (boto3 client creation, put_object with public-read ACL, or URL composition). The original exception text is passed through as the message and chained via `from e`.

Solutions

  1. Read the chained exception (str(e)) to identify the underlying boto3 error and fix its specific cause (keys, region, bucket name).
  2. Verify AWS credentials and region via `aws sts get-caller-identity` and confirm the bucket exists in that region.
  3. Check bucket settings: ACLs may be disabled (Object Ownership=Bucket owner enforced) — switch to bucket policies instead of ACL='public-read'.
  4. Confirm network connectivity/endpoint (VPC endpoints, proxy settings) to the S3 service.

Example fix

// before
try:
    self.client.put_object(Bucket=bucket_name, Key=filename, Body=file_bytes, ACL="public-read")
except Exception as e:
    raise OssServiceException(*c9010)(str(e)) from e
// after
try:
    self.client.head_bucket(Bucket=bucket_name)  # fail fast with clearer error
    self.client.put_object(Bucket=bucket_name, Key=filename, Body=file_bytes, ACL="public-read")
except ClientError as e:
    logger.error(f"S3 upload failed: {e.response['Error']['Code']}")
    raise OssServiceException(*c9010)(str(e)) from e
Defensive patterns

Strategy: try-catch

Validate before calling

# before upload
client.head_bucket(Bucket=bucket_name)  # raises ClientError early if missing/no perms
assert os.environ.get("AWS_ACCESS_KEY_ID") and os.environ.get("AWS_SECRET_ACCESS_KEY")

Type guard

def s3_config_ok(client, bucket: str) -> bool:
    try:
        client.head_bucket(Bucket=bucket)
        return True
    except ClientError:
        return False

Try / catch

try:
    url = s3_client.upload_file(bucket, filename, data)
except OssServiceException as e:
    if "NoSuchBucket" in str(e): fix_bucket_name()
    elif "InvalidAccessKeyId" in str(e) or "SignatureDoesNotMatch" in str(e): rotate_credentials()
    raise

Prevention

When it happens

Trigger: upload_file calls self.client.put_object(Bucket, Key, Body, ACL='public-read') and boto3 raises: InvalidAccessKeyId, SignatureDoesNotMatch, NoSuchBucket, EndpointConnectionError, or any network/TLS failure.

Common situations: Wrong AWS keys or region in env/config; bucket deleted or name typo; no network/VPC route to S3 endpoint; boto3 not configured (missing credentials); bucket policy blocking put-object or ACL writes (ACLs disabled by Object Ownership: Bucket owner enforced).

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at core/common/service/oss/s3_service.py:120

        Upload a file to S3-compatible storage with public read access.

        :param filename: The name of the file to be uploaded
        :param file_bytes: The binary content of the file to upload
        :param bucket_name: Optional bucket name, uses default if not provided
        :return: The public download URL for the uploaded file
        :raises CustomException: If file upload fails
        """
        if not bucket_name:
            bucket_name = self.bucket_name

        try:
            # Set public read access
            self.client.put_object(
                Bucket=bucket_name, Key=filename, Body=file_bytes, ACL="public-read"
            )
            return f"{self.oss_download_host}/{bucket_name}/{filename}"
        except Exception as e:
            raise OssServiceException(*c9010)(str(e)) from e


class IFlyGatewayStorageClient(BaseOSSService, Service):
    """
    iFly Gateway Storage client implementation.

    This class provides file upload functionality using iFly's proprietary
    gateway storage service with HMAC authentication.
    """

    def __init__(
        self,
        endpoint: str,
        access_key_id: str,
        access_key_secret: str,
        bucket_name: str,
        ttl: int,
    ):

View on GitHub (pinned to 5e758547a8)