Sume image 400 'does not accept aspect_ratio': read supported (Python)
When a Sume image row rejects aspect_ratio with 400 invalid_request, the error carries a supported array. This Python snippet picks the nearest listed ratio.

When a Sume image row does not list the aspect ratio you sent, the API returns 400 invalid_request with a message saying the model does not accept aspect_ratio and a supported array of the values it does accept. Read that array and pick the nearest ratio to the one you wanted. The Python below does it in about 25 lines.
The behaviour is in the image generation code on origin/main and matches the Image API docs, which say a value outside a row's descriptor is rejected rather than approximated. I read both on 2026-10-10 and did not call the live API.
The snippet
The helper posts the request and returns the status with the parsed body, including for error responses. When the status is 400 it reads supported, drops auto because that is not a numeric ratio, and picks the listed value whose width over height is closest to the one requested. I look in error first and then at the top level, because I have only read the shape in code and not captured a live body.
import json, os, urllib.error, urllib.request
def post(body):
req = urllib.request.Request(
"https://api.sume.com/v1/images",
data=json.dumps(body).encode(),
headers={"Authorization": "Bearer " + os.environ["SUME_API_KEY"],
"Content-Type": "application/json"},
)
try:
with urllib.request.urlopen(req, timeout=60) as r:
return r.status, json.load(r)
except urllib.error.HTTPError as e:
return e.code, json.load(e)
def nearest(supported, want):
a, b = want.split(":")
t = int(a) / int(b)
ok = [s for s in supported if s != "auto"]
return min(ok, key=lambda s: abs(int(s.split(":")[0]) / int(s.split(":")[1]) - t))
status, data = post({"model": "x-ai/grok-image", "prompt": "a red kettle", "aspect_ratio": "4:5"})
if status == 400:
err = data.get("error", data)
print(nearest(err["supported"], "4:5"))Which rows will trigger it
Rows that omit common ratios are the likely triggers. The Grok Imagine row does not list 4:5, 5:4 or 21:9. Nano Banana Pro does not list 4:1, 1:4, 8:1 or 1:8. Imagen 4 rows list only five ratios. Higgsfield Soul lists seven. Seedream 5.0 Lite lists nine and no auto.
| Row | Ratios listed | Notable gaps |
|---|---|---|
| Imagen 4 Fast and Ultra | 5 | everything but the five core ratios |
| Higgsfield Soul | 7 | fewer than most rows |
| Seedream 5.0 Lite and 4.5 | 9 | no auto |
| Nano Banana Pro | 11 | no 4:1, 1:4, 8:1, 1:8 |
| Grok Imagine | 13 | no 4:5, 5:4, 21:9 |
Do not hide the substitution
Snapping 4:5 to 3:4 changes the crop, and snapping 21:9 to 16:9 changes the width. That may be fine for a draft and wrong for a placement that has hard dimensions. Decide per use: for a draft, log the swap and continue; for a final, fail the job and route it to a row that lists the ratio.
Either way, record the original ratio, the substituted one and the row id next to the result. When someone asks why an ad is slightly narrower than the brief, the log answers it.
- Retry once with the substituted ratio, not in a loop.
- Never retry a 400 with the same body.
- Add a catalog check in CI so the first sight of the error is not in production.
- Use the list route to see the values before you send.
Related errors
A 400 for an unlisted parameter such as quality on a row that lacks it has the same shape of cause: the descriptor does not list it. The errors and credits page describes the error families, so route them by status code and type rather than by message text, which can be reworded.
Testing the fallback
Unit-test nearest with plain lists, since it has no network dependency. A request for 4:5 against the Grok list should pick 3:4 or 1:1 by the numeric distance, and you should check which one your rule returns and that you like it. 4:5 is 0.8, 3:4 is 0.75 and 1:1 is 1.0, so 3:4 wins. Write that expectation as an assertion so a later change cannot silently alter it.
Sources
Related posts
More in Developers
- How do I ask Sume for 2K? Only 5 of 19 image rows list resolution
Only Nano Banana 2.1, Nano Banana Pro, Imagen 4 Ultra, Ideogram 4.5 and Soul list a resolution field. Send it to FLUX, Seedream or GPT and you get a 400.
- Sume job error details.input_field: the parameter that failed
When a provider rejects one request field, Sume publishes its name as details.input_field beside provider_error_message. Map it back to your body and fix it.
- Sume job failed artifact_too_large: shrink the output
A finished file that storage refuses with HTTP 413 fails as artifact_too_large and is not retryable. Shorten the cut, lower the resolution or the bitrate.
- Sume content_policy_rejected: image, music and video messages
Sume scans a provider's rejection text for six phrases and answers with one of three fixed content-policy messages and next_action fix_input.
Written by Sume