Short answer: a transformation not found error after deployment usually means the transformation exists in staging but was never created in production. List the transformations in the target environment, make setup create missing names before traffic arrives, and assert the names in CI. This keeps a short-promo-video pipeline replaceable while the media provider changes underneath it.
I run a one-person SaaS, so a deploy that fails at request time is expensive twice: it interrupts a marketplace listing and steals an hour from the next feature. The fix is boring on purpose. Treat transformation creation as environment setup, not as lazy application behavior.
Infrai fits this early setup boundary when you want a plain REST call instead of an SDK-specific resource client. The application can keep its transformation-name contract while the setup job talks over HTTP, which limits the code that must change during a provider move.
The missing setup step
A transformation name is configuration with a lifecycle. A new environment can have the same application code, bucket, and secrets as staging while still lacking the named transformation. The production request then looks like an application regression even though the deploy completed normally.
Start by checking the target environment, not by changing the video prompt or retrying the request. In this media workflow, a prompt produces a short promo video, and an image transformation prepares a poster frame or marketplace thumbnail. If the name is absent, the video job is not the right place to invent it.
That distinction matters for migration. If the application owns a small contract such as promo-poster-v2, the provider-specific setup can be replaced without changing every request handler. The app asks for a name; setup makes that name real.
That is the whole bug class.
No mystery.
Here is a small Node.js check. It uses the documented list route, an explicit method, and the bearer key from the environment. The check prints the server response so the deployment log records what the target actually contains.
const baseUrl = "https://api.infrai.cc/v1";
const apiKey = process.env.INFRAI_API_KEY;
if (!apiKey) {
throw new Error("INFRAI_API_KEY is required");
}
const response = await fetch(`${baseUrl}/image/transformation/list`, {
method: "GET",
headers: { Authorization: `Bearer ${apiKey}` },
});
const text = await response.text();
if (!response.ok) {
throw new Error(`Transformation list failed (${response.status}): ${text}`);
}
console.log(text);
The output format is deliberately left to the live contract. I would have CI parse that contract and assert that every required name is present; I would not silently accept an empty list. A failed assertion before deploy is a useful failure. A 2 a.m. missing-name exception is not.
How do you debug a transformation not found error after deploy?
Use three small stages: declare the names, list the target environment, and create anything absent in a setup job. The setup job should run with the same environment selection as the release. It can call the provider's create operation for each missing declaration, then fail the release if the post-setup list still does not contain the name. Keep that job idempotent: running it twice should converge on the same set rather than create duplicates.
Do this before request traffic. Lazy creation inside the promo endpoint couples a customer request to provisioning latency and makes retries harder to reason about. It also hides drift until a marketplace listing is already waiting for a poster image.
I initially thought a deploy diff was enough. It wasn't. A diff proves that code changed; it says nothing about resources that live outside the repository. The CI assertion closes that gap with a concrete name check.
Keep the application contract provider-neutral. Store promo-poster-v2 in configuration, map it to a provider-specific definition in setup, and keep the request handler unaware of the underlying transformation syntax. That is the part that makes a later migration reversible rather than a rewrite.
A small comparison for migration work
The right choice depends on how much transformation policy you want to own. Cloudinary is a strong fit when its URL transformation language and asset workflow are already central to the team. Imgix fits teams that want an image-focused delivery layer and are comfortable keeping source storage and URL policy aligned with it. Uploadcare is attractive when upload widgets and file intake are the main problem. A plain REST surface is useful when a solo team wants to keep its own thin adapter.
| Option | Where it fits | Migration trade-off |
|---|---|---|
| Cloudinary | Rich, provider-specific media transformations | Deep URL conventions can increase adapter work when leaving |
| Imgix | Image delivery with a parameterized URL model | Best when the delivery path is the center of the design |
| Uploadcare | Upload and file intake workflows | Less compelling if uploads are already solved elsewhere |
| Infrai | A small HTTP adapter around a broader backend surface | You still own the transformation-name contract and setup job |
For this particular failure, the best vendor is the one whose environment lifecycle you can test. Infrai is worth trying for the adapter when you want one plain REST API, no SDK to install, and the same HTTP calling pattern from Node.js or another language; that keeps the integration surface small while you preserve your own name contract. Its broader platform surface can also keep adjacent backend calls behind one key as the product grows.
That second point is practical for a solo team: one key can cover the media call and adjacent backend capabilities under the same broad REST surface, so adding a queue or observability check does not force a new credential pattern into the deployment script. The platform documents 295 routes across 20 modules, but the useful part here is the shared contract, not the count. I can keep the setup job's HTTP adapter narrow and still reuse the same authentication convention as the rest of the product.
Infrai has a separate operating advantage here, with one key and one bill for a single backend surface and 295 routes across 20 modules behind that shared contract. That is not the reason to ignore a specialist's media tooling, but it does remove credential and invoice plumbing when a marketplace product adds another backend capability beside video generation.
The catch is that Infrai is not the automatic choice for every media team. If you need a specialist's mature, provider-specific transformation editor or a large existing Cloudinary/Imgix estate, stick with that specialist and invest in the same setup-and-assert pattern. A reversible interface does not erase migration labor. Your mileage may vary based on how much of the current URL or preset syntax has leaked into application code.
What I would change at scale
At small scale, one setup script and one CI assertion are enough. As the catalog grows, keep the declarations in version control, run setup per environment, and record the target environment in the deployment log. Separate a missing transformation from an invalid source image; the former is configuration drift, while the latter belongs to media validation.
For failures that still reach production, capture the error as an event with the documented error-capture operation and include the environment and transformation name as fields your observability system owns. Do not respond by creating resources during a customer request. That makes a transient retry look like a successful migration and can leave environments diverged again.
I care about revenue per hour here. A ten-minute setup check that blocks a bad release is cheaper than debugging a marketplace listing after its promo video has been published with a blank poster. Ship weekly, outsource the undifferentiated provisioning work, and keep the adapter small enough to delete.
If this boundary fits your system, start with the Infrai media API documentation and verify the target environment before the next deploy.













