# Why a generation failed

A generation that ends with `status: "failed"` carries an `error`. A failed generation is never charged: the reservation is released and `price_usd` only shows what it would have cost. Branch on `code`; `message` is written for people and can change.

```json
{
  "data": {
    "id": "gen_4Fq9xT2mLr7Kd1sV8bN3pZ0c",
    "object": "generation",
    "status": "failed",
    "model": "bytedance-lipsync",
    "price_usd": 0.45,
    "outputs": [],
    "error": {
      "code": "invalid_input",
      "message": "The `audio` is 12.4 s long, longer than `duration` (9). Send 13.",
      "retryable": false
    },
    "created_at": "2026-11-01T18:04:11.000Z",
    "finished_at": "2026-11-01T18:04:19.000Z"
  }
}
```

| Field | Type | What it is |
| - | - | - |
| `code` | string | Stable. See the table below. |
| `message` | string | What happened and what to change. |
| `retryable` | boolean | Whether the same request may work if you send it again. Sending again is a new generation with a new `Idempotency-Key`; a failed one costs nothing. |
| `reason` | string | Only on `content_policy`: the kind of block, `sexual`, `minors`, `copyright`, `real_person` or `other`. |

| Code | Retryable | Why | Fix |
| - | - | - | - |
| `content_policy` | No | The prompt or a file was blocked by a content policy. `reason` says which kind. | Change the prompt or the input. |
| `invalid_input` | No | A file or an option cannot be used: the wrong type, a link that did not open, too large, too long, or longer than `duration`. The message says which and what to send. | Check the file and the model's `params`, or [upload the file](https://docs.vidlab.ai/uploads). |
| `model_declined` | No | The model is not offered with these options right now. | Try other options, such as another resolution or duration. |
| `reference_changed` | No | The reference clip is longer than the request was priced for. | Send the `extra.video_seconds` the message gives. |
| `max_cost_exceeded` | No | The measured price is over your `max_cost_usd`. | Raise `max_cost_usd`, or lower the resolution or duration. |
| `max_wait_exceeded` | No | No route could finish inside your `max_wait_s`. | Raise `max_wait_s`. |
| `model_busy` | Yes | No route can take this model right now. | Try again in a few minutes, or use another model. |
| `model_unavailable` | Yes | The model is switched off for the moment. | Try again later, or use another model. |
| `all_routes_failed` | Yes | Every route that could take the call turned it away. | Try again in a few minutes. |
| `timeout` | Yes | A route did not answer in time, or the generation ran for longer than 6 hours. | Try again, or shorten the request. |
| `processing_failed` | Yes | The route could not make it, or the result could not be delivered. | Try again, or change the prompt. |

Failures that happen before a generation exists (a bad body, no credit) are request errors, see [Errors](https://docs.vidlab.ai/errors).
