Fail startup when a pinned image model id leaves Sume's catalog
Google's replacement for gemini-2.5-flash-image was itself retired. Add a startup check that your pinned model ids still appear in GET /v1/images/models.

Pin your image model ids in config, and on boot compare them with GET /v1/images/models; exit if any pinned id is absent. Vendor retirements chain: Google's own page says gemini-2.5-flash-image shut down October 2, 2026, and the replacement it named was itself retired. A boot check turns that into one clear error.
Why a chain of replacements bites
The Gemini API deprecations page lists gemini-2.5-flash-image with a shutdown of October 2, 2026 and a recommended replacement of gemini-3.1-flash-image-preview. The same page shows that preview id shut down June 25, 2026, pointing to the GA gemini-3.1-flash-image. Copying the first replacement you find can land you on an id that is already gone.
Sume's side of it
Sume's catalog is the list of ids you can actually call. GET /v1/images/models returns them in data[], each with an id such as google/nano-banana-2. An id not in that list gets a 404 model_not_found from /v1/images. Checking the list first moves that failure from a user request to deployment.
The check
Run it in your deploy step or app boot. It needs a non-empty key and exits non-zero on a miss.
const pinned = ["google/nano-banana-2", "ideogram/ideogram-v4.5"];
const res = await fetch("https://api.sume.com/v1/images/models", {
headers: { Authorization: `Bearer ${process.env.SUME_API_KEY}` },
});
if (!res.ok) throw new Error(`catalog fetch failed: ${res.status}`);
const { data } = await res.json();
const live = new Set(data.map((m) => m.id));
const missing = pinned.filter((id) => !live.has(id));
if (missing.length) {
console.error("Missing from catalog:", missing.join(", "));
process.exit(1);
}
console.log("All pinned image models are listed.");What to do on a miss
Do not auto-switch to a different model silently: price, aspect-ratio sets and reference limits differ between models. Fail the deploy, then choose a replacement by capability using the catalog descriptors, as in filtering the catalog by capability.
If you want to be told about additions rather than removals, see diffing the catalog. The two checks are complementary: one guards what you depend on, the other watches what appeared.
Keep the list short
Pin only ids your product calls. A long list of every model you have ever tried makes the check noisy, and an alert people learn to ignore protects nothing.
Run it in CI too
The same script works as a scheduled CI job. Run it daily against the production key's catalog and you hear about a removal before the next deploy rather than after. Keep the pinned list in one file that both the app and the check import, so the two cannot drift apart.
If you use org-slug ids, pin the exact id string your code sends. The docs describe bare and org-slug forms; the check above compares the strings you send against the catalog id values, so use the form your catalog response shows.
What the check does not catch
Presence in the list says a model can be called, not that its behaviour is unchanged. Parameters, price and reference limits can change while the id stays the same. For those, read the capability descriptors on each model entry and compare them with what your code sends, or log usage.cost per request and alert when it moves.
Sources
Related posts
More in Developers
- If a lip-sync job fails on Sume, is the reserved money refunded?
Yes. Sume reserves the price at admit, captures on completion and refunds on failure. For a 5-second H3 Max lip-sync at 768p the reservation is $0.50.
- Failed Sume job: read category, retryable and next_action first
Failed jobs expose public error metadata: category, stage, retryable, retry-after, reason and next action. Map each category to retry, fix or stop.
- fal retries failed requests up to 10 times; on Sume the retry is yours
fal's queue retries transient errors up to 10 times unless you send X-Fal-No-Retry. On Sume the retry is yours: reuse the Idempotency-Key, never resubmit blind.
- fal never drops queued requests; Sume can answer 429 queue_full
fal's queue docs say queued requests are never dropped. Sume caps accepted jobs per plan and returns 429 queue_full when full. Plan for the gap.
Written by Sume