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 images 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.
MynthAPIErrorThrown for any non-2xx response on a create, upload, estimate, or models call.
| Property | Holds |
|---|---|
status | The HTTP status |
code | The body's error.code, when there is one |
message | The body's error.message, or a generic fallback |
issues | One { path, message } per invalid field, on a validation_error |
taskId | The task the create made before it failed, on public_access_token_failed |
message says what to change, so it is safe to show as it is. When a field
failed the schema, issues has the same problems one by one, with path
pointing into the request body:
try {
await mynth.image.generate({
model: "black-forest-labs/flux.2-pro",
prompt: "A lighthouse at dusk",
count: 50,
});
} catch (error) {
if (error instanceof MynthAPIError && error.code === "validation_error") {
for (const issue of error.issues ?? []) {
console.error(issue.path.join("."), issue.message);
// count count must be at most 20 (was 50)
}
}
throw error;
}A validation error that is not about one field, such as a size the model
cannot produce, has no issues. See
validation errors.
Two failures are not MynthAPIError:
Error when you first read mynth.image or
mynth.video.fetch throws. The
create is not retried. There are no idempotency keys, so check
GET /tasks before you resend a create that may have gone through.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_contentA provider refusal usually fails one output, not the task. wait() returns,
and urls is shorter than count. Read
failures for each 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.
TaskAsyncTimeoutError.