مدیریت خطاها
فرمتهای خطا و نحوه مقابله با آنها
مستندات
کد خطا را دارم، معنی آن چیست؟
| کد | یعنی چه | کجا را بخوانم |
|---|---|---|
| 400 | درخواست شما ایراد دارد: فیلدی جا افتاده، کد مدل اشتباه است، یا پارامتری پشتیبانی نمیشود. | پارامترهای درخواست |
| 401 | کلید API نامعتبر است، منقضی شده، یا هدر Authorization درست ساخته نشده. | احراز هویت |
| 402 | یا موجودی کیف پول تمام شده (insufficient_funds) یا سقف بودجهٔ ماهانهٔ همین کلید پر شده (budget_exceeded). | بررسی موجودی |
| 403 | دسترسی مسدود شده است. | تماس با پشتیبانی |
| 429 | به سقف نرخ درخواست رسیدهاید. هدر Retry-After میگوید چقدر صبر کنید. | محدودیت نرخ درخواست |
| 500 | خطای داخلی سرور. درخواست شما ایرادی ندارد؛ با فاصلهٔ فزاینده دوباره تلاش کنید. | حل مشکلات |
اگر کد خطا ندارید و فقط نشانهای میبینید (درخواست معلق میماند، stream وسط کار قطع میشود، تصویر ساخته نمیشود) از حل مشکلات شروع کنید که بر پایهٔ نشانه مرتب شده است.
فرمت پاسخ خطا
تمام خطاها از فرمت OpenAI-compatible پیروی میکنند:
{ "error": { "message": "فیلد model الزامی است", "type": "invalid_request_error", "code": "model_required", "param": "model" }}برای تشخیص خودکار، به code نگاه کنید نه به message: پیام برای خواندن آدم است و ممکن است تغییر کند، اما code یک شناسهٔ پایدار است. جدول بعدی همین کلید را فهرست میکند.
فهرست خطاهای متداول
فهرست خطاهای متداول و فرمت پاسخ:
| کد HTTP | error | توضیح |
|---|---|---|
| 400 | model_required | فیلد model ارسال نشده است. |
| 400 | model_not_found | مدل فعال/مجاز یافت نشد (کُد اشتباه یا غیرفعال). |
| 401 | unauthorized | کلید API نامعتبر یا ارسال نشده است. |
| 402 | insufficient_funds | اعتبار کیف پول کافی نیست. |
| 402 | budget_exceeded | سقف بودجه ماهانه این کلید API پر شده است. |
| 429 | rate_limited | عبور از سقف درخواست. هدرهای Retry-After و سایر هدرهای نرخ محدودیت بازگردانده میشوند. |
| 400 | unsupported_parameter | برخی پارامترها پشتیبانی نمیشوند. |
| 500 | server_error | خطای داخلی. |
خطاهای مربوط به پیوست (تصویر و سند) همگی 400 با نوع invalid_request_error هستند و جدول خودشان را دارند:
| code | معنی | چه کار کنید |
|---|---|---|
| document_input_not_supported | ارائهدهندهٔ این مدل PDF نمیپذیرد. | همان محتوا را به شکل .txt یا .md بفرستید — فایل متنی روی هر مدلی کار میکند. یا یک مدل Anthropic / OpenAI / OpenRouter بردارید. جدول در ورودی فایل. |
| unsupported_file_type | نه PDF است و نه یک نوع متنی شناختهشده؛ یا بایتها با نوع اعلامشده نمیخوانند؛ یا HTML است. | یک PDF بفرستید، یا فایل متنی با پسوند شناختهشده. نوع از روی محتوا تشخیص داده میشود، نه برچسب. |
| invalid_file_encoding | فایل متنی UTF-8 معتبر نیست و charset هم اعلام نشده. | فایل را UTF-8 ذخیره کنید، یا charset را در data URI بنویسید: data:text/plain;charset=windows-1256;base64,… |
| file_too_large | PDF از ۸ مگابایت بزرگتر است، یا فایل متنی از ۲۵۶ کیلوبایت، یا مجموع متن یک درخواست از ۵۱۲ کیلوبایت. | فایل را فشرده کنید یا بخش کوچکتری از آن را بفرستید. سقف روی فایل خام است، نه روی رشتهٔ Base64. |
| invalid_file_data | data URI خراب است یا Base64 نامعتبر. | کدگذاری را درست کنید. |
| unsupported_attachment | file_id فرستاده شده، بخش فایل هیچ دادهای ندارد، یا یک ویدیو بهصورت نشانی فرستاده شده، از جمله لینک یوتیوب. برخلاف تصویر و فایل که نشانی عمومی هم میپذیرند، ویدیو و صوت فقط Base64 میپذیرند. | file_data را مستقیم بفرستید؛ file_id پشتیبانی نمیشود. ویدیو را هم بهصورت data URI بفرستید، نه نشانی. |
| too_many_attachments | بیش از ۱۰ نشانی متمایز در یک درخواست، یا بیش از ۲ ویدیو در یک درخواست. | بهجای نشانی، Base64 بفرستید؛ برای ویدیو تعداد کلیپها را به حداکثر ۲ عدد کاهش دهید. |
| image_too_large | تصویر از سقف ۸ مگابایت بزرگتر است. | فشرده یا کوچک کنید. سقف روی فایل خام است، نه روی Base64. |
| image_fetch_timeout | درگاه نتوانست نشانی را بهموقع دانلود کند. | دسترسپذیری را بررسی کنید، یا Base64 بفرستید. |
| image_fetch_failed | دانلود ناموفق بود. | همان بالا. بعضی میزبانها دانلود خودکار را رد میکنند. |
| image_url_blocked | نشانی به یک آدرس خصوصی یا رزروشده میرسد. | از یک نشانی عمومی استفاده کنید. |
| image_fetch_busy | تعداد دانلود همزمان زیاد است. | دوباره تلاش کنید، یا Base64 بفرستید. |
| audio_input_not_supported | مدل انتخابشده صدا نمیپذیرد. | یک مدل با قابلیت «ورودی صوت» بردارید — فهرست بهروز در ورودی صوت. |
| audio_too_large | کلیپ صوتی پس از رمزگشایی از Base64 از ۲۰ مگابایت بزرگتر است. | کلیپ را کوتاهتر یا فشردهتر بفرستید. |
| unsupported_audio_type | فرمت صوتی جزو فرمتهای پذیرفتهشده نیست. | به یکی از wav, mp3, aiff, aac, ogg, flac, m4a, pcm16, pcm24 تبدیل کنید. |
| invalid_audio | رمزگشایی Base64 شکست خورد یا داده خراب است. | کدگذاری Base64 را بررسی کنید. |
| video_input_not_supported | مدل انتخابشده ویدیو نمیپذیرد. | یک مدل با قابلیت «ورودی ویدیو» بردارید. فهرست بهروز در ورودی ویدیو. |
| video_too_large | کلیپ ویدئویی پس از رمزگشایی از Base64 از ۲۰ مگابایت بزرگتر است. | کلیپ را کوتاهتر یا فشردهتر بفرستید. |
| unsupported_video_type | فرمت ویدیو جزو فرمتهای پذیرفتهشده نیست. | به یکی از mp4, mpeg, mov (quicktime), webm تبدیل کنید. |
| invalid_video | رمزگشایی Base64 شکست خورد یا داده خراب است. | کدگذاری Base64 را بررسی کنید. |
کدهایی که با image_ شروع میشوند برای سند و فایل متنی هم صادر میشوند. هر دو از یک دانلودکنندهٔ مشترک میآیند و نام آنها عوض نشده، پس دیدن image_fetch_timeout روی یک PDF عجیب نیست و اشتباه هم نیست.
خطاهای رایج
401 Unauthorized
علل:
- کلید API نامعتبر یا منقضی شده
- هدر Authorization نادرست
- هدر Authorization گمشده
429 Rate Limited
راهحل:
- هدر X-RateLimit-Remaining را بررسی کنید
- قبل از تکرار، مدت زمان Retry-After را منتظر بمانید
- exponential backoff استفاده کنید
402 Payment Required (billing_error)
این خطا دو حالت دارد که با فیلد code از هم متمایز میشوند:
insufficient_funds (موجودی کیف پول کافی نیست
- موجودی حساب را در داشبورد بررسی و حساب را شارژ کنید
- از مدلهای ارزانتر استفاده کنید
budget_exceeded) سقف بودجه ماهانه این کلید API پر شده است
- کیف پول سازمان ممکن است موجودی داشته باشد، اما این کلید به سقف بودجه ماهانهاش رسیده است
- سقف بودجه کلید را از داشبورد سازمان افزایش دهید یا تا ماه بعد صبر کنید
نمونه پاسخ خطا
نمونه پاسخ خطا (429):
HTTP/1.1 429 Too Many RequestsRetry-After: 17X-RateLimit-Limit: 60X-RateLimit-Remaining: 0Content-Type: application/json { "error": { "message": "Rate limit exceeded. Allowed 60 requests per 60 seconds.", "type": "rate_limit_error", "code": "rate_limited", "param": null }}نمونه پاسخ خطا (400 model_not_found):
HTTP/1.1 400 Bad RequestContent-Type: application/json { "error": { "message": "The requested model 'gpt-unknown' was not found or is disabled.", "type": "invalid_request_error", "code": "model_not_found", "param": "model" }}نمونه پاسخ خطا (402 budget_exceeded):
HTTP/1.1 402 Payment RequiredContent-Type: application/json { "error": { "message": "This API key has reached its monthly budget limit.", "type": "billing_error", "code": "budget_exceeded", "param": null }}تلاش مجدد
برای 429 و 500 تلاش مجدد با فاصلهٔ فزاینده (exponential backoff) کار درست است؛ نمونهٔ کامل در محدودیت نرخ درخواست آمده. برای 400، 401 و 402 تلاش مجدد بیفایده است، تا وقتی چیزی را عوض نکنید، همان پاسخ برمیگردد.