xtekky/gpt4free · error · Exception

Failed to get download URL

Error message

Failed to get download URL

What it means

Raised inside LMArena's image upload helper after a POST to the getSignedUrl Next.js server action. The response body is expected to contain a line prefixed '1:' whose JSON payload carries {success: true, data: {url: ...}}. This instance fires when that payload has success set to false, i.e. the server processed the action but refused to issue a signed download URL.

Source

Thrown at g4f/Provider/needs_auth/LMArena.py:516

                ) as response:
                    await raise_for_status(response)
                async with session.post(
                    url=cls.url,
                    json=[key],
                    headers={
                        "accept": "text/x-component",
                        "content-type": "text/plain;charset=UTF-8",
                        "next-action": cls._next_actions["getSignedUrl"],
                        "referer": cls.url,
                    },
                ) as response:
                    await raise_for_status(response)
                    text = await response.text()
                    line = next(
                        filter(lambda x: x.startswith("1:"), text.split("\n")), ""
                    )
                    if not line:
                        raise Exception("Failed to get download URL")

                    chunk = json.loads(line[2:])
                    if not chunk.get("success"):
                        raise Exception("Failed to get download URL")
                    image_url = chunk.get("data", {}).get("url")
                    uploaded_file = {
                        "name": key,
                        "contentType": file_type,
                        "url": image_url,
                    }
                debug.log(f"Uploaded image to: {image_url}")
                ImagesCache[image_hash] = uploaded_file
                files.append(uploaded_file)
        return files

    @classmethod
    def read_args(cls, args: dict = {}):
        cache_file = cls.get_cache_file()

View on GitHub (pinned to 973504e177)

Solutions

  1. Refresh authentication: delete the LMArena cache/args file and let get_args_from_nodriver re-create cookies (or pass lmarena_args), then retry
  2. Update g4f to the latest version so cls._next_actions server-action IDs match the current LMArena build
  3. Inspect debug logs (debug.log) for the raw response text to confirm whether the '1:' payload is success:false or an HTML Cloudflare challenge page
  4. Reduce media payload: use a common content type (image/jpeg, image/png) and smaller file size

Example fix

// before
resp = await client.chat.completions.create(model='...', messages=[...], media=[open('heic.img','rb')])

// after
# refresh auth + use a standard image type
img = Image.open('photo.heic').convert('RGB'); img.save('/tmp/photo.jpg', 'JPEG')
resp = await client.chat.completions.create(model='...', messages=[...], media=[open('/tmp/photo.jpg','rb')])
Defensive patterns

Strategy: retry

Validate before calling

from g4f.Provider.needs_auth.LMArena import LMArena
args = LMArena.read_args()
if not args:
    raise SystemExit('Authenticate LMArena first (no cached args)')

Type guard

def lmarena_has_auth(args) -> bool:
    return bool(args) and isinstance(args, dict) and bool(args.get('cookies'))

Try / catch

try:
    resp = await client.chat.completions.create(model=..., messages=msgs, media=[img])
except Exception as e:
    if 'Failed to get download URL' in str(e):
        # refresh auth once, then retry with a standard image type
        await refresh_lmarena_auth()
        resp = await client.chat.completions.create(model=..., messages=msgs, media=[converted_img])
    else:
        raise

Prevention

When it happens

Trigger: Calling LMArena with media/image attachments: upload_files() POSTs to cls.url with header next-action = cls._next_actions['getSignedUrl']; the returned '1:' line parses as JSON with success != true (e.g. {'success': false}).

Common situations: The Next.js server-action ID changed after an LMArena deploy (stale _next_actions mapping), an expired or Cloudflare-challenged session still returning 200 HTML/JSON, or an image type/size the signed-URL endpoint rejects.

Related errors


AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14). Data as JSON: /api/errors/80f8400608938f40. Report an issue: GitHub.