Errors
MynthAPIError for a rejected request, the TaskAsync errors a wait can throw, and how to read the codes of a task that failed.
The SDK surfaces failures three ways:
| What failed | What you get |
|---|---|
| The HTTP request was rejected | MynthAPIError is thrown |
The task settled as failed, or the wait broke | A TaskAsync* error is thrown |
Some items failed on a completed task | Nothing is thrown. urls and getImages() are shorter |
The codes themselves are on errors. This page is how the SDK reports them.
import Mynth, { MynthAPIError, TaskAsyncTaskFailedError } from "@mynthio/sdk";
const mynth = new Mynth();
const pending = await mynth.image
.generateAsync({
model: "black-forest-labs/flux.2-pro",
prompt: "A lighthouse at dusk, film grain",
})
.catch((error: unknown) => {
if (error instanceof MynthAPIError && error.code === "INSUFFICIENT_BALANCE") {
// rejected at create: nothing queued, nothing held
}
throw error;
});
try {
const task = await pending.wait();
console.log(task.urls[0]);
} catch (error) {
if (error instanceof TaskAsyncTaskFailedError) {
// read GET /tasks/{pending.id} for errors[].code
}
throw error;
}Keep the id from generateAsync() before you wait. When generate() throws,
the task id is only in the error message, and the error classes have no
taskId property.
MynthAPIError#
Thrown for any non-2xx response on a create, upload, estimate, or models call.
| Property | Holds |
|---|---|
status | The HTTP status |
code | The body's code, when there is one |
message | The body's message, or a generic fallback |
A schema rejection is status 400 with code undefined and an unhelpful
message, because that body has an issue list instead of a code, and the
SDK does not keep the list. On error.status === 400 without a code, repeat
the request with curl or npx @mynthio/cli ... --json to see which field
failed. See schema rejections.
Two failures are not MynthAPIError:
- A missing API key throws a plain
Errorwhen you first readmynth.imageormynth.video. - A network failure on the create request throws whatever
fetchthrows. The create is not retried. There are no idempotency keys, so checkGET /tasksbefore you resend a create that may have gone through.
Errors while waiting#
All are exported from @mynthio/sdk, and none carries a task error code.
| Class | Thrown when |
|---|---|
TaskAsyncTaskFailedError | The task settled as failed. The message includes the task id |
TaskAsyncTimeoutError | The poll budget ran out: 30 minutes for images and tools, one hour for video |
TaskAsyncUnauthorizedError | Status or the task record answered 401 or 403 |
TaskAsyncFetchError | Status reads kept failing. cause is the last network error, when there was one |
TaskAsyncTaskFetchError | The task completed, but loading the record kept failing |
For TaskAsyncTaskFailedError, read GET /tasks/{id}. Its errors array is
[{ code, message? }]. Branch on code.
After TaskAsyncTimeoutError the task is still running on Mynth. Read it by
id later instead of creating it again.
RESTRICTED_CONTENT#
A provider refusal usually fails one output, not the task. wait() returns,
and urls is shorter than count. Read
getImages({ includeFailed: true }) for each error.code. If the refusal
failed the whole task, wait() throws TaskAsyncTaskFailedError, and the
code is on GET /tasks/{id}. Prompts and images
explains the refusal.
Next steps#
- Tasks and polling: the poll budget behind
TaskAsyncTimeoutError. - Errors: every HTTP and task code.