iflytek/astron-agent · error · Exception

Failed to download image from

Error message

Failed to download image from {image_url}

What it means

Raised in BaseNode._assemble_messages when downloading an image for an image-understanding LLM call fails: requests.get(image_url) returned a non-200 status. This is a plain Exception (not CustomException) because image download is considered an unexpected runtime failure while assembling chat messages.

Solutions

  1. Verify the image URL is reachable (curl it) and re-upload/re-generate a fresh presigned URL if expired
  2. Ensure the image is publicly accessible from the workflow service or pass credentials appropriately
  3. Fix the upstream node/variable that produced the wrong image URL
  4. Add retry with backoff for transient 5xx and pre-validate URLs before executing the node

Example fix

// before
image_url = "https://minio/bucket/old.png?expires=..."  // expired
// after
image_url = refresh_presigned_url("bucket", "old.png")
Defensive patterns

Strategy: try-catch

Validate before calling

import requests
def image_url_reachable(url: str) -> bool:
    try:
        return requests.head(url, timeout=5).status_code == 200
    except requests.RequestException:
        return False

Try / catch

try:
    await node._chat_with_llm(...)
except Exception as e:
    if str(e).startswith("Failed to download image from"):
        log.error("image unavailable: %s", e)
        return fallback_text_only_response()
    raise

Prevention

When it happens

Trigger: Calling _chat_with_llm on a node configured with an image_url where the URL returns 404/403/5xx, points to an expired signed URL, or the storage object was deleted.

Common situations: Expired MinIO/S3 presigned URLs saved in old workflow runs; private images requiring auth headers that requests.get does not send; mistyped image URLs in node inputs; network/DNS failures inside the cluster.

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/a82fdddfca067a3e. Report an issue: GitHub.

Appendix: source

Thrown at core/workflow/engine/nodes/base_node.py:1202

            # Handle images in history
            if payload_comp_history and payload_comp_history[0].content_type == "image":
                if self.source == ModelProviderEnum.OPENAI.value:
                    payload_comp_history.pop(0)
                if self.source == ModelProviderEnum.XINGHUO.value:
                    image_models = os.getenv(
                        "SPARK_IMAGE_MODEL_DOMAIN", "image,imagev3"
                    ).split(",")
                    if self.domain in image_models:
                        if not image_url:
                            image_url = payload_comp_history[0].content
                        payload_comp_history.pop(0)
        # If it's an image understanding model, reserve the first position in array for image
        if image_url:
            import requests  # type: ignore

            image_response = requests.get(image_url)
            if image_response.status_code != 200:
                raise Exception(f"Failed to download image from {image_url}")
            image_msg = {
                "role": "user",
                "content": str(
                    base64.b64encode(image_response.content).decode("utf-8")
                ),
                "content_type": "image",
            }
            await span_context.add_info_events_async({"image": str(image_url)})
        # Don't upload base64
        if image_msg:
            await span_context.add_info_events_async(
                {"user_message": json.dumps(user_message[1:], ensure_ascii=False)}
            )
        else:
            await span_context.add_info_events_async(
                {"user_message": json.dumps(user_message, ensure_ascii=False)}
            )
        history = [

View on GitHub (pinned to 5e758547a8)