エラーと拒否理由
エラーコードと拒否理由の完全なカタログです。
エラーレスポンスの形式
HTTPエラーレスポンス(ミドルウェア)
ミドルウェアからの構造化JSONエラー(HTTP 4xx/5xx)です:
{
"error": "<code>",
"message": "<human message>"
}
エンジンレベルの拒否(HTTP 200)
取引の拒否は HTTP 200 で返され、OrderUpdateMessage.status = "REJECTED" となります:
{
"timestamp": 1735000000000,
"info": { ... },
"status": "REJECTED",
"reason": "<exact rejection string>",
"filled_size": 0,
"order_id": null,
"wallet_address": "0x...",
"mmp_triggered": false
}
重要: 取引の拒否についてHTTPステータスコードに依存しないでください。必ず status フィールドと reason フィールドを確認してください。
ミドルウェアのエラーコード
これらは構造化JSONボディを持つHTTPエラーレスポンスとして返されます。
| コード | HTTPステータス | 説明 |
|---|---|---|
invalid_request | 400 | リクエストボディを読み取れません |
invalid_json | 400 | JSONのパースに失敗しました |
missing_field | 400 | 必須フィールドが欠落しています |
invalid_wallet | 400 | ウォレット文字列をパースできませんでした |
invalid_parameter | 400 | 無効なパラメータ(例: size/priceは文字列である必要があります) |
signature_verification_failed | 400 | EIP-712署名のリカバリーに失敗しました |
unsupported_endpoint | 400 | ミドルウェアがこのパスをサポートしていません |
unauthorized | 401 | 署名者がウォレットに対して認可されていません(エージェント認証失敗) |
internal_error | 500 | エージェント認可チェックが予期せず失敗しました |
エンジンの拒否理由
これらは status="REJECTED" のときに OrderUpdateMessage.reason に表示されます。
満期を迎えた銘柄
理由: "Instrument has expired"
原因: すでに満期を迎えた銘柄に対して注文が発注されました。
対処: GET /instruments または GET /markets で銘柄の満期を確認してください。
資金のないアカウント
理由: "Account has no funds. Please deposit before trading."
原因: アカウントの現金残高が <= 0.0 です。
対処: 取引前にウォレットにUSDCを入金してください。
証拠金不足
理由: "Insufficient margin: required={:.2}, available={:.2}, shortfall={:.2}"
例: "Insufficient margin: required=1500.00, available=1200.00, shortfall=300.00"
原因: 取引前の証拠金チェックにおいて、提案された注文後の証拠金要件をカバーするには利用可能な担保(エクイティ)が不足していると判定されました。
スタンダードマージンアカウントの場合、必要な担保はオプションの売買方向、オプションの種類、行使価格、原資産価格、および現在のポートフォリオに依存します。現行のローンチ時証拠金モデルについてはスタンダードマージンを参照してください。
対処:
GET /portfolio?wallet=...でポートフォリオを確認する- 証拠金で証拠金の計算方法を確認する
- ポジションサイズを縮小するか、担保を追加する
スポット価格の欠落
理由: "Failed to get portfolio: No spot price available for underlying: {underlying}"
原因: エンジンが約定シミュレーションに必要な原資産のスポット価格を推定できません。
対処: Hyperliquidのスポット価格フィードの接続を確認してください。スポット価格は allMids WebSocketフィードから取得されます。
ティア制限
理由: "Tier1 users cannot go short. Filled long position: {filled}, total sell orders (including new): {total} (symbol: {symbol})"
原因: ウォレットが tier1(買いのみ)であり、十分な約定済みロングポジションがないのに売却を試みました。
対処:
GET /user-tier?wallet=...でティアを確認する- すべての売り注文が約定済みロングポジションでカバーされていることを確認する
- マーケットメイカー統合のためにライター権限が必要な場合はHypercallに連絡する
無効なシンボル
理由: "Invalid symbol: {symbol}"
原因: そのシンボルに対するオーダーブックが存在しません。
対処:
GET /instrument-specsとGET /marketsでマーケットが存在することを確認する- シンボル形式を確認する:
UNDERLYING-YYYYMMDD-STRIKE-(C|P)
シンボルのパースエラー
理由: "Failed to parse symbol: {detail}"
原因: シンボルが期待される形式に一致しません。
対処: シンボル形式が UNDERLYING-EXPIRY-STRIKE-(C|P) またはDeribitスタイルの DDMMMYY に一致することを確認してください。
キャンセルの失敗
注文が見つからない
理由: "Order not found for cancellation: {client_id}"
原因: 指定された client_id の注文が見つかりません。
対処: client_id が正しいこと、および GET /orders?wallet=... で注文が存在することを確認してください。
オーダーブックが見つからない
理由: "Orderbook not found for symbol: {symbol}"
原因: そのシンボルに対するオーダーブックが存在しません。
対処: シンボルが有効であること、およびマーケットが存在することを確認してください。
注文がオーダーブックに存在しない
理由: "Order {id} not found in orderbook {symbol}"
原因: 注文IDは存在しますが、注文がオーダーブックにありません(約定済みまたはキャンセル済みの可能性があります)。
対処: GET /orders?wallet=... で注文ステータスを確認してください。
注文がすでに約定済み
理由: "Order {id} is already filled and cannot be cancelled"
原因: キャンセルリクエストの前に注文が完全に約定しました。
対処: GET /orders?wallet=... で注文ステータスを確認してください。
注文がすでにキャンセル済み
理由: "Order {id} was already cancelled"
原因: 注文はすでにキャンセルされています。
対処: GET /orders?wallet=... で注文ステータスを確認してください。
パーペチュアル注文のバリデーション
理由: "Perp order missing underlying symbol"
原因: パーペチュアル注文に underlying フィールドが含まれていません。
対処: パーペチュアル注文に underlying シンボルが含まれていることを確認してください。
MMPトリガー
理由: "MMP triggered during fill processing"
原因: 約定処理中にMMPリミットに違反しました。注文は部分的に約定した後、MMPがトリガーされ残りの数量がキャンセルされました。
対処:
GET /mmp-config?wallet=...¤cy=...でMMP設定を確認する- 約定ウィンドウのメトリクスを確認する
- MMPリミットを調整するか、
POST /mmp-config/resetでMMP状態をリセットする
MMPの詳細な仕様についてはMMPを参照してください。
MMPキャンセル(その他の注文)
理由: "Order canceled by MMP trigger"
原因: 同じウォレット+原資産に対する別の注文がMMPをトリガーしたため、注文がキャンセルされました。
対処: MMP設定と約定アクティビティを確認してください。
ハンドラーレベルのバリデーションエラー
これらはエンジンに到達する前にHTTP 400を返します。
価格のバリデーション
エラー: "Price validation failed: Price {price} has {n} significant figures, maximum allowed is 5"
原因: 価格が有効数字5桁を超えています。
対処: 価格を有効数字5桁以下に丸めてください。
サイズ/価格の形式
エラー: "Size must be greater than 0" または "Price must be greater than 0"
原因: サイズまたは価格が <= 0 であるか、浮動小数点数としてパースできません。
対処: size と price が有効な正の数値(文字列として)であることを確認してください。
無効なシンボル形式
エラー: ハンドラーのエラーメッセージ付きのHTTP 400
原因: シンボルが有効なオプションシンボルとしてパースできません。
対処: シンボル形式を確認してください: UNDERLYING-YYYYMMDD-STRIKE-(C|P)。
バルク注文のエラー
バルクエンドポイントは BulkOrderResult.error に項目ごとのエラーを返します:
"Signature verification failed: ...""Unauthorized: signer not authorized for wallet""Price validation failed: ...""Size must be greater than 0""Price must be greater than 0""Failed to send order to engine""No response from engine"
各結果には index(リクエスト配列内の位置)と success ブール値が含まれます。
WebSocketエラー
WebSocketの制御メッセージです:
{
"type": "Error",
"message": "Authentication required for this channel"
}
よくあるエラー:
"Authentication required for this channel":?wallet=なしでプライベートチャネルへの購読を試みました"Client not found": 内部エラー(接続が失われました)
エラーハンドリングのベストプラクティス
- 必ず
statusフィールドを確認する: 取引の拒否についてHTTPステータスコードに依存しないでください reason文字列をパースする: プログラムによる処理には正確な理由文字列を使用してください- バルクエラーを処理する: バルクリクエストの各項目について
BulkOrderResult.errorを確認してください - リトライロジック:
REJECTEDとなった注文はリトライしないでください(まず根本原因を修正してください) - ロギング: 拒否のデバッグのために
OrderUpdateMessage全体をログに記録してください
エラーコードリファレンス表
| 拒否理由 | カテゴリ | HTTPステータス | 対処 |
|---|---|---|---|
Instrument has expired | 満期 | 200 | 満期を確認し、別の銘柄を使用する |
Account has no funds... | 資金 | 200 | 資金を入金する(実装済みの場合) |
Insufficient margin: ... | 証拠金 | 200 | サイズを縮小、担保を追加、ポートフォリオを確認する |
Failed to get portfolio: No spot price... | データ | 200 | Hyperliquidフィードの接続を確認する |
Tier1 users cannot go short... | ティア | 200 | tier2にアップグレードするか、売りをカバーする |
Invalid symbol: ... | シンボル | 200 | マーケットが存在することを確認する |
Order not found for cancellation: ... | キャンセル | 200 | 注文が存在することを確認する |
Order {id} is already filled... | キャンセル | 200 | 注文はすでに執行済み |
Order {id} was already cancelled | キャンセル | 200 | 注文はすでにキャンセル済み |
MMP triggered during fill processing | MMP | 200 | MMP設定を確認し、リミットを調整する |
Order canceled by MMP trigger | MMP | 200 | MMP設定を確認し、リミットを調整する |
signature_verification_failed | 認証 | 400 | 署名と文字列エンコーディングを確認する |
unauthorized | 認証 | 401 | エージェントを承認するか、ウォレットで署名する |
Price validation failed: ... | バリデーション | 400 | 価格を有効数字5桁以下に丸める |
拒否のデバッグ
- 注文の詳細を確認する:
symbol、price、size、sideが正しいことを確認する - ポートフォリオを確認する:
GET /portfolio?wallet=...で現在のポジションと現金を確認する - ティアを確認する:
GET /user-tier?wallet=...でティア制限を確認する - MMPを確認する:
GET /mmp-config?wallet=...¤cy=...でMMPリミットを確認する - マーケットを確認する:
GET /marketsとGET /instrumentsで銘柄が存在することを確認する - ログを確認する: サーバーログに追加のコンテキストが含まれている場合があります(APIでは公開されません)
参考情報
- 拒否ロジック: 取引エンジンで強制されます
- 証拠金チェック: 注文の受け付け前に適用されます
- ティアチェック: ウォレットのティアごとに強制されます
- ハンドラーのバリデーション: 標準的なリクエストバリデーション