نسخه بتا · دانا به‌زودی عرضه می‌شود
مستندات

خطاها

هر کد خطای API دانا، علتش و کاری که باید بکنید، با نمونه پاکت خطا

هر خطا یک پاسخ JSON با کد HTTP درست است. دو رابط دانا دو شکل پاکت جدا دارند: مسیرهای /v1/messages پاکت Anthropic می‌گیرند و بقیه مسیرها پاکت OpenAI.

جدول تشخیص سریع

کدچه اتفاقی افتادهکار بعدی
400بدنه درخواست ناقص یا نامعتبر استپیام خطا فیلد مقصر را می‌گوید؛ همان را درست کنید
401کلید نیست یا شناخته نشدهدر Authorization: Bearer ... را بررسی کنید
402اعتبار مسیر بالادست تمام شدهتلاش مجدد بی‌فایده است؛ با پشتیبانی تماس بگیرید
403کلید معتبر است ولی این مسیر را نداردمسیرهای internal فقط برای سرویس‌های داخلی دانا هستند
404مسیر یا منبع وجود نداردآدرس و شناسه مدل را بازبینی کنید
413بدنه درخواست از سقف بزرگ‌تر استپیام‌ها را کوتاه یا تکه‌تکه کنید
429نرخ درخواست، ظرفیت، سقف توکن یا اعتباربه بخش ۴۲۹ بروید؛ چهار حالت جداگانه دارد
500خطای پیش‌بینی‌نشده در گیت‌ویبا backoff تا سه بار تلاش مجدد کنید
502گیت‌وی به موتور مدل نرسیدتلاش مجدد کنید؛ اگر ادامه داشت گزارش بدهید
503سرویس‌دهی مدل هنوز روشن نشدهتلاش مجدد نکنید؛ code را بخوانید
504موتور مدل به‌موقع جواب نداددرخواست را کوچک‌تر کنید و دوباره بفرستید

شکل پاکت خطا

رابط OpenAI (/v1/chat/completions، /v1/models و بقیه):

{
  "error": {
    "message": "Invalid API key.",
    "type": "authentication_error",
    "param": null,
    "code": null
  }
}

param همیشه null است. فیلد code فقط در چند خطای مشخص مقدار می‌گیرد و در بقیه null می‌ماند.

رابط Anthropic (/v1/messages و /v1/messages/count_tokens):

{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key."
  }
}

دقت کنید که پاکت Anthropic یک type: "error" در سطح بیرونی هم دارد. SDK رسمی Anthropic روی همین فیلد حساب می‌کند.

مقدار type بر اساس کد

کدرابط OpenAIرابط Anthropic
400invalid_request_errorinvalid_request_error
401authentication_errorauthentication_error
403permission_errorpermission_error
404not_found_errornot_found_error
409conflict_errorapi_error
413invalid_request_errorrequest_too_large
429rate_limit_errorrate_limit_error
بقیهapi_errorapi_error

خطاها به تفکیک کد

400 - درخواست نامعتبر

پیام خطا دقیقا می‌گوید کجا ایراد دارد. رایج‌ترین‌ها:

{"error": {"message": "Request body must include a 'messages' array.", "type": "invalid_request_error", "param": null, "code": null}}
پیامعلتراه‌حل
Request body must include a 'messages' array.بدنه JSON نیست یا messages نداردساختار بدنه را با Chat Completions بسنجید
Request body must be a JSON object.بدنه count_tokens آبجکت نیستیک آبجکت JSON بفرستید
Invalid X-Dana-Harness value ...مقدار هدر harness اشتباه استیکی از سه مقدار none یا base یا agent
Invalid effort ...سطح effort ناشناخته استچهار سطح مجاز low و medium و high و max

خطاهای اعتبارسنجی خودکار (نوع اشتباه یک پارامتر، مثلا temperature رشته‌ای) هم همین 400 را می‌گیرند و متن خطا فهرست فیلدهای مقصر را برمی‌گرداند.

401 - احراز هویت ناموفق

{"error": {"message": "Missing API key.", "type": "authentication_error", "param": null, "code": null}}

چهار حالت جدا با چهار پیام جدا:

  • Missing API key. هدر Authorization ارسال نشده.
  • Invalid API key. کلید در پایگاه داده پیدا نشد؛ شاید غیرفعال شده یا حرفی جا افتاده.
  • internal_app key requires X-Dana-User-Id and X-Dana-Session-Id. مربوط به کلیدهای داخلی است.
  • X-Dana-User-Id is only valid with an internal_app key. این هدر را از درخواست بردارید.

اگر کلید تازه ساخته‌اید و همچنان 401 می‌گیرید، فاصله یا خط جدید اضافه در متغیر محیطی را بررسی کنید. شرح کامل را در احراز هویت بخوانید.

402 - اعتبار بالادست تمام شده

{"error": {"message": "Router credit/quota exhausted.", "type": "insufficient_quota", "param": null, "code": "router_credit_exhausted"}}

این خطا به حساب شما ربط ندارد؛ مربوط به مسیر بالادست دانا است. تلاش مجدد جوابش را عوض نمی‌کند.

403 - دسترسی ممنوع

کلید درست است اما اجازه این مسیر را ندارد. مسیرهای /internal/... فقط با کلید internal_app باز می‌شوند و برای مصرف‌کننده عمومی API در دسترس نیستند.

413 - بدنه بیش از حد بزرگ

گیت‌وی پیش از خواندن بدنه، Content-Length را با سقف پیکربندی‌شده می‌سنجد و درخواست را همان‌جا رد می‌کند.

{"error": {"message": "Request body too large.", "type": "invalid_request_error", "param": null, "code": null}}

تاریخچه مکالمه را کوتاه کنید یا متن‌های بلند را تکه‌تکه بفرستید.

کد 429 - چهار حالت جدا

429 چهار علت متفاوت دارد. اول type را بخوانید، بعد تصمیم بگیرید.

۱. عبور از نرخ درخواست کلید - type: "rate_limit_error"

{"error": {"message": "Rate limit exceeded.", "type": "rate_limit_error", "param": null, "code": null}}

این پاسخ چهار هدر هم دارد:

  • Retry-After
  • X-RateLimit-Limit
  • X-RateLimit-Remaining
  • X-RateLimit-Reset

به جای عدد ثابت، به Retry-After گوش بدهید. جزئیات را در محدودیت‌ها ببینید.

۲. اتمام اعتبار - type: "insufficient_quota"

{"error": {"message": "You have insufficient credit. Please top up your balance.", "type": "insufficient_quota", "param": null, "code": "insufficient_quota"}}

تلاش مجدد کمکی نمی‌کند. از بخش اعتبار کنسول شارژ کنید.

۳. رسیدن به سقف پنجره توکن - type: "window_cap"

این حالت پاکت مخصوص خودش را دارد و روی رابط OpenAI عینا برگردانده می‌شود:

{
  "error": {
    "type": "window_cap",
    "which": "session_4h",
    "reset_at": "<ISO 8601 timestamp>",
    "upgrade_url": "https://console.dana.expert/plans"
  }
}
فیلدمعنا
whichکدام پنجره پر شده: session_4h یا weekly
reset_atلحظه دقیق باز شدن پنجره، به وقت UTC
upgrade_urlنشانی ارتقای پلن در کنسول

تا رسیدن reset_at صبر کنید؛ تلاش زودتر همین جواب را می‌گیرد. روی رابط Anthropic همین خطا با پاکت استاندارد Anthropic و نوع rate_limit_error برمی‌گردد.

۴. پرشدن ظرفیت لحظه‌ای - type: "capacity_busy"

فیلد eta_seconds تخمین زمان خالی شدن صف را می‌دهد؛ این یکی ارزش تلاش مجدد دارد.

500 - خطای داخلی

{"error": {"message": "Internal server error.", "type": "api_error", "param": null, "code": null}}

پاسخ عمدا جزئیات ندارد. x-request-id را از هدر پاسخ بردارید و همان را به پشتیبانی بدهید؛ لاگ سمت ما با همین شناسه پیدا می‌شود.

502 و 504 - مشکل موتور مدل

کدپیامtypeمعنا
502Cannot reach the model backend.api_errorگیت‌وی نتوانست به موتور وصل شود
504Upstream model timed out.timeout_errorموتور در مهلت مقرر جواب نداد

هر دو گذرا هستند. روی 504 علاوه بر تلاش مجدد، max_tokens را کمتر کنید.

503 - سرویس‌دهی مدل روشن نیست

{"error": {"message": "Dana model serving is coming soon.", "type": "api_error", "param": null, "code": "coming_soon"}}

روی رابط Anthropic:

{"type": "error", "error": {"type": "api_error", "message": "Dana model serving is coming soon."}}

در این حالت چهار مسیر مدل بسته‌اند:

  • /v1/chat/completions
  • /v1/completions
  • /v1/messages
  • /v1/models

بقیه سرویس سر جایش است: ساخت کلید، شارژ اعتبار و گزارش مصرف کار می‌کنند. تلاش مجدد روی این خطا بی‌فایده است.

سیاست تلاش مجدد

import random
import time

import httpx

RETRYABLE = {429, 500, 502, 503, 504}


def call(payload, api_key, max_attempts=3):
    for attempt in range(max_attempts):
        response = httpx.post(
            "https://api.dana.expert/v1/chat/completions",
            headers={"Authorization": f"Bearer {api_key}"},
            json=payload,
            timeout=120,
        )
        if response.status_code not in RETRYABLE:
            response.raise_for_status()
            return response.json()

        body = response.json().get("error", {})
        # این حالت‌ها با تلاش مجدد درست نمی‌شوند.
        if body.get("type") == "window_cap" or body.get("code") in (
            "coming_soon",
            "insufficient_quota",
        ):
            raise RuntimeError(body.get("message"))

        wait = float(response.headers.get("Retry-After", 2**attempt))
        time.sleep(wait + random.random())

    raise RuntimeError("سه تلاش پیاپی ناموفق بود")

قاعده‌های پشت این کد:

  • روی 429 با type: "rate_limit_error" یا capacity_busy تلاش مجدد کنید، با backoff نمایی و کمی jitter.
  • روی 429 با window_cap یا insufficient_quota تلاش مجدد نکنید؛ اولی زمان مشخص دارد، دومی شارژ می‌خواهد.
  • روی 503 با code برابر coming_soon صبر کنید تا اعلام راه‌اندازی.
  • 4xx غیر از 429 را در کد خودتان مدیریت کنید. همان درخواست، همان جواب.
  • x-request-id هر پاسخ را لاگ کنید. بدون آن، پیگیری یک خطای تک‌باره تقریبا ناممکن است.

صفحه‌های مرتبط