# エラーコード

すべてのエラーに共通の形式、各コードの意味、発生したときの対処法。

> https://nezhagate.com/ja/docs/guide/errors

## エラー形式

`/v1` のエンドポイントでエラーが起きると、4xx / 5xx のステータスコードと、下の例のような JSON を返します。`message` は人が読むための説明、`type` はエラーの大分類、`code` は変わらない機械可読の識別子、`param` は問題のあるフィールドです（該当しない場合は `null`）。判定には HTTP ステータスコードと `code` を使い、`message` の文面では判定しないでください。英語、中国語、またはその両方で書かれることがあり、言い回しも変わります。

```
{
  "error": {
    "message": "Insufficient balance — please top up",
    "type": "insufficient_quota",
    "code": "insufficient_quota",
    "param": null
  }
}
```

`/anthropic` のエンドポイントは Anthropic 独自の形式で、`code` と `param` はありません。HTTP ステータスコードと `error.type` で判定してください：

```
{
  "type": "error",
  "error": {
    "type": "not_found_error",
    "message": "model: gpt-5.5"
  }
}
```

- エラーによっては、トップレベルに追加のフィールドが付きます。たとえば、すべての回線が混み合っているときの `attempts` や、一時的に使える回線がないときの `retry_after` です。知らないフィールドは無視してください。

- モデル提供元がリクエストを拒否した場合（コンテキストが長すぎるときなど）、`message` はモデル提供元の原文、`code` はモデル提供元が返した値です。値がない場合は `invalid_request` になります。

## HTTP ステータスコード早見表

| HTTP | 発生する場面 |
| --- | --- |
| **400** | パラメータの誤り、または存在しないモデル（`model_not_found` など）。`error.param` が該当フィールドを示します。 |
| **401** | キーがない、または無効・停止中（`missing_api_key`、`invalid_api_key`）。 |
| **402** | 残高不足、またはキーが予算の上限に達しました（`insufficient_quota`）。 |
| **403** | このキーのモデル許可リストにそのモデルが入っていないか、キーの IP 許可リストの外からのリクエストです（`permission_denied`）。 |
| **404** | パスが存在しないか、タスク ID が存在しない・3 日間の記録保存期間を過ぎた・別のアカウントが送信したタスクです（`job_not_found`）。 |
| **429** | このキーに設定した 1 分あたりの上限か無料モデルの 1 日の枠を超えたか、このモデルのすべての回線が混み合っています（`rate_limit_exceeded`）。`Retry-After` があればその秒数、なければ数秒待ってから再試行してください。 |
| **502** | 上流のエラーまたはタイムアウトで、回線を切り替えても失敗しました。理由は `code`（`upstream_timeout`、`upstream_unavailable` など）に入ります。課金されないので、そのまま再試行できます。 |
| **503** | モデルのメンテナンス中（`model_maintenance`）、または当サイト側の一時的なエラー（`service_unavailable`）です。課金されないので、しばらくして再試行してください。 |

## すべてのエラーコード

ゲートウェイが返すエラーをカテゴリ別にまとめています。1 つの HTTP ステータスコードに複数のコードが対応することがあるので、`code` で判断してください。

### 認証とアカウント

| HTTP | code | 原因 | 対処 |
| --- | --- | --- | --- |
| **401** | `missing_api_key` | `Authorization: Bearer` ヘッダーがありません。`/v1` のエンドポイントは `x-api-key` を読みません。 | `Authorization: Bearer YOUR_API_KEY` を付けてください。 |
| **401** | `invalid_api_key` | キーが存在しない・削除された・無効化されているか、アカウントが停止されています。 | コンソールの「API Keys」ページでキーを確認してください。 |
| **402** | `insufficient_quota` | アカウントの残高を使い切りました（貸し越し枠の下限を下回っています）。 | チャージしてから再試行してください。 |
| **403** | `permission_denied` | キーの IP 許可リストの外からのリクエストです。 | 許可リストにある IP から呼び出すか、コンソールで許可リストを変更してください。 |

### キーに設定した制限

| HTTP | code | 原因 | 対処 |
| --- | --- | --- | --- |
| **429** | `rate_limit_exceeded` | このキーに設定した 1 分あたりのリクエスト数の上限を超えました（直近 60 秒で数えます）。`Retry-After` ヘッダーは付きません。 | 数秒待ってから再試行するか、コンソールでこのキーの上限を引き上げてください。 |
| **429** | `rate_limit_exceeded` | 無料モデルの 1 日の枠を使い切りました（アカウントごと、UTC の 1 日単位）。`message` で代わりに使える有料モデルが案内されることがあります。 | UTC 0 時を過ぎてから使うか、有料モデルに切り替えてください。 |
| **402** | `insufficient_quota` | このキーの 1 日の予算（UTC の 1 日単位）または合計の利用上限を使い切りました。 | 翌日になってから使うか、コンソールで上限を引き上げてください。 |
| **403** | `permission_denied` | そのモデルがキーのモデル許可リストに入っていません。 | 許可リストにあるモデルを使うか、コンソールで許可リストを変更してください。 |

### リクエストの内容

| HTTP | code | 原因 | 対処 |
| --- | --- | --- | --- |
| **400** | `invalid_json` / `invalid_encoding` | リクエスト本文が正しい JSON ではありません。UTF-8 でない場合は `invalid_encoding` になります。 | JSON の構文と文字コードを確認してください。 |
| **400** | `invalid_request` | パラメータが不正です。たとえば、本文が JSON オブジェクトでない、`n` が整数でない、参照画像や参照動画を読み込めない（どれがなぜ読めないかは `message` に記載）、`/v1/images/edits` に参照画像がない、動画の長さ / 解像度 / 比率 / 参照素材の数がそのモデルの範囲外、などです。 | `message` の内容に沿って直してから、もう一度送信してください。 |
| **400** | `invalid_messages` / `invalid_role` / `invalid_max_tokens` | 対話リクエストの `messages` がない・空・形式が正しくない、`role` が許可された値ではない、または `max_tokens` が正の整数ではありません。`param` が該当するフィールドを示します。 | `param` が示すフィールドを直してください。 |
| **400** | `missing_prompt` | `/v1/images/generations` に `prompt` がありません。 | `prompt` を追加してください。 |
| **400** | `unsupported_resolution` | このモデルには選択した解像度のグレードがありません（たとえば Grok の画像生成には 4K がありません）。 | 別のグレードを選んでください。各モデルが対応するグレードは、そのドキュメントに載っています。 |
| **400** | `invalid_callback_url` | `callback_url` が公開された http(s) のアドレスではないか、2000 文字を超えています。 | インターネットからアクセスできるアドレスを使ってください。 |
| **400** | `max_tokens_too_small` | 推論モデルが `max_tokens` をすべて思考に使い切り、回答を書けませんでした（ストリーミングしない対話）。 | `max_tokens` を増やしてから再試行してください。 |
| **404** | `not_found` | エンドポイントのパスが存在しません。 | パスを確認してください。すべてのエンドポイントは [API リファレンス](https://nezhagate.com/ja/docs/api) に載っています。 |
| **404** | `job_not_found` | タスク ID が存在しない・3 日間の記録保存期間を過ぎた・別のアカウントが送信したタスクのいずれかです。画像タスクを動画のエンドポイントで照会した場合（その逆も）も、このエラーになります。 | タスク ID と照会先のエンドポイントを確認してください。結果のリンクは 60 日間保存され、タスクの記録が期限切れになっても影響を受けません。 |

### モデルの状態

| HTTP | code | 原因 | 対処 |
| --- | --- | --- | --- |
| **400** | `model_not_found` | モデル ID のつづりが違う・`model` がない・そのモデルをこのエンドポイントでは使えない（たとえば対話モデルで画像のエンドポイントを呼び出した）のいずれかです。 | `GET /v1/models` または [API リファレンス](https://nezhagate.com/ja/docs/api) にあるモデル ID を使ってください。 |
| **400** | `model_disabled` | モデルの提供が終了しました。 | 別のモデルに切り替えてください。後継モデルがある場合、古いモデルのページは自動でそちらへ移動します。 |
| **400** | `model_coming_soon` | モデルは発表済みですが、まだ呼び出しを受け付けていません。 | 公開のお知らせをお待ちください。 |
| **503** | `model_maintenance` | モデルのメンテナンス中で、リクエストを受け付けていません。その間、別のモデルが代わりに回答することもありません。 | メンテナンスが終わってから再試行してください。状況は [サービス状態](https://nezhagate.com/ja/status) で確認できます。 |

### 容量と残高の確保

| HTTP | code | 原因 | 対処 |
| --- | --- | --- | --- |
| **402** | `insufficient_quota` | このリクエストの分を確保するだけの残高がありません。ゲートウェイはまずリクエストにかかりうる最大の費用を確保するため、同時に多くの呼び出しを送ったときにも起こることがあります。 | 一度に多くの呼び出しを送った直後なら、数秒待って再試行してください。そうでなければチャージしてください。 |
| **429** | `rate_limit_exceeded` | このモデルのすべての回線が混み合っていて、リクエストは送られませんでした。対話エンドポイントでのみ発生し、画像と動画のタスクは拒否されずに順番待ちになります。OpenAI 互換のエンドポイントでは `Retry-After` が付きます。 | `Retry-After` の秒数だけ待ってから再試行してください。 |
| **503** | `service_unavailable` | 当サイト側の一時的なエラーです（参照素材の保存に失敗した場合など）。`/v1/responses` で一時的に使える回線がないときも、`Retry-After` 付きで 503 を返します。 | しばらくしてから再試行してください。 |

### 上流のエラー（対話エンドポイント）

対話エンドポイント（`/v1/chat/completions`、`/v1/responses`、`/anthropic/v1/messages`）でエラーが起きると、ゲートウェイはまずほかの回線で再試行し、すべての回線が失敗したときに限って次のいずれかのエラーを返します。どれも課金されません。

| HTTP | code | 原因 | 対処 |
| --- | --- | --- | --- |
| **502** | `upstream_timeout` | 回線がタイムアウトしました（最初のトークンがなかなか返ってこない場合を含みます）。 | 再試行してください。長い回答には `stream: true` を使ってください。 |
| **502** | `upstream_unavailable` | 回線でエラーが起きたか、一時的に利用できません。 | しばらくしてから再試行してください。 |
| **502** | `upstream_busy` | モデル提供元がレート制限をかけています。モデル提供元の 429 をそのまま 429 として返すことはなく、代わりにこの 502 を返します。 | しばらくしてから再試行してください。 |
| **502** | `upstream_connection_error` | モデル提供元との接続が切れました。 | 再試行してください。 |
| **502** | `empty_completion` | モデル提供元が空の内容を返しました。リクエストの内容に対する判定ではありません。 | 再試行してください。 |
| **502** | `upstream_error` | 回線が回答の代わりにエラーの文を返しました。 | 再試行してください。 |
| **400** | `content_filter` | モデルはリクエストを処理しましたが、何も返しませんでした。多くの場合、内容がモデル提供元の安全ポリシーに触れたためです。 | プロンプトを調整してから再試行してください。同じプロンプトのままでは、たいてい再び拒否されます。 |
| **502** | `upstream_prompt_filter` | モデル提供元の事前チェックでプロンプトが止められました。モデルによる判定ではありません。 | しばらくしてから再試行するか、言い回しを少し変えてください。 |
| **4xx** | — | モデル提供元がリクエストを拒否しました（コンテキストが長すぎる、対応していないパラメータがあるなど）。ステータスコードと `message` はモデル提供元が返したまま渡され、`code` はモデル提供元の値です。 | `message` の内容に沿ってリクエストを変更してください。 |

### Anthropic のエンドポイント

- `error.type` はステータスコードに応じて Anthropic の標準値になります：400 `invalid_request_error`、401 `authentication_error`、402 `billing_error`、403 `permission_error`、404 `not_found_error`、429 `rate_limit_error`（すべての回線が混み合っているときは `overloaded_error`）、502 `api_error`、503 `overloaded_error`（モデルのメンテナンス中は `api_error`）。

- `/anthropic` は Claude モデルだけを受け付けます。それ以外のモデルには 404 `not_found_error` が返ります。

- `max_tokens` は必須で、0 にはできません。満たさない場合は 400 が返ります。

## 失敗したタスク（画像と動画）

画像・動画のタスクが受け付けられた後に失敗した場合も、照会エンドポイントは HTTP 200 を返し、`status` は `failed` になります。理由は `error` に入り、`error.code` は下の表のいずれかの値です。このタスクのために確保したクレジットは残高に戻っています。Webhook を使っている場合は、同じ内容の `image.failed` / `video.failed` を受け取ります。

| code | 発生する場面 | 対処 |
| --- | --- | --- |
| `content_policy` | 動画：プロンプト、参照素材、または生成された映像や音声がコンテンツ審査を通りませんでした（音声が引っかかった場合は `param` が `audio` になります）。 | プロンプトを書き直すか参照素材を差し替えてから、もう一度送信してください。同じ内容のままでは再び拒否されます。 |
| `moderation_blocked` | 画像：モデル提供元の安全審査がプロンプトまたは参照画像を拒否しました（コードが `content_policy_violation` の場合もあります）。 | プロンプトを書き直すか、参照画像を差し替えてください。そのまま再送信しても、たいてい再び拒否されます。 |
| `render_failed` | 動画：今回は動画が生成されませんでした。多くは一時的なものです。 | 同じリクエストをそのまま再送信すれば、たいてい成功します。 |
| `invalid_material` | 動画：上流が入力素材に問題があると判断しました。大まかな分類のエラーで、一時的なことも多くあります。 | まずはそのまま再送信してください。繰り返し起きる場合は、参照素材とプロンプトの長さを確認してください。 |
| `render_timeout` | 動画：順番待ちまたはレンダリングに時間がかかりすぎ、上流がこのタスクを打ち切りました。 | もう一度送信してください。 |
| `wait_timeout` | 動画：この回線で許される最長の待ち時間を過ぎても、動画が届きませんでした。 | もう一度送信してください。 |
| `upstream_unstable` | 動画：レンダリング中に接続が切れました。 | もう一度送信してください。 |
| `result_fetch_failed` | 動画は生成されましたが、当サイト側でのダウンロードまたは保存が繰り返し失敗しました。 | もう一度送信してください。 |
| `invalid_request` | 動画：この回線はこのパラメータの組み合わせ（長さ、比率、解像度など）を受け付けません。 | `message` の内容に沿ってパラメータを調整し、もう一度送信してください。 |
| `upstream_error` | その他の失敗：すべての回線を試しても失敗した、順番待ちが 15 分を過ぎても始まらなかった、上流が理由を示さずに拒否した、などです。具体的な状況は `message` に書かれています。 | たいていは再送信すれば成功します。 |

[非同期タスクの詳しい説明 →](https://nezhagate.com/ja/docs/guide/async-jobs)

## ストリーミング中のエラー

- ストリーミングのリクエストが HTTP 200 を返して出力を始めた後は、エラーが起きてもステータスコードは変わりません。`error` を含むデータイベントとしてストリーム内に届くか、ストリームがそのまま終わります。

- ストリームが最後まで届いたかを確認してください。OpenAI 形式では `finish_reason` と `data: [DONE]`、Anthropic 形式では `message_stop` を受け取ったかを見ます。受け取っていなければ、途中で切れたものとして扱ってください。

- 途中で切れたストリーミングは、切れるまでに生成された分だけが課金されます。詳しくは [課金と返金](https://nezhagate.com/ja/docs/guide/billing) をご覧ください。

## エラーは課金されますか？

- エラーを返したリクエストは一切課金されません。課金の前にエラーになるか、確保額が全額戻るかのどちらかです。

- 失敗した画像・動画のタスクは全額返金されます。

- 唯一の例外は、すでに出力が始まったストリーミングです。途中で切れた場合は、切れるまでに生成された分を課金します。

## 再試行の判断

4xx の場合は、まずリクエストを直してください（402 ならチャージ、429 なら少し待つ）。5xx とタイムアウトはそのまま再試行してかまいません。間隔は指数バックオフで空け、`Retry-After` があればその秒数だけ待ってください。

[再試行の方法とサンプルコード →](https://nezhagate.com/ja/docs/guide/rate-limits#retry)
