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
- Refresh authentication: delete the LMArena cache/args file and let get_args_from_nodriver re-create cookies (or pass lmarena_args), then retry
- Update g4f to the latest version so cls._next_actions server-action IDs match the current LMArena build
- 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
- 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
- Authenticate once via nodriver so cached args exist before using media
- Convert images to JPEG/PNG before upload
- Keep g4f updated — LMArena server-action IDs change with deploys
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
- No authentication arguments found.
- No auth file found and nodriver is not available.
- Invalid response: {last_msg}
- Failed to obtain Turnstile token for DeepInfra request.
- No response
AI-assisted analysis of xtekky/gpt4free@973504e177 (2026-08-14).
Data as JSON: /api/errors/80f8400608938f40.
Report an issue: GitHub.