Zum Inhalt springen
Fehlerbehandlung

Fehlerbehandlung

Eine Anfrage, die fehlschlägt, gibt einen HTTP-Statuscode und einen JSON-Body mit einem Fehlertyp und einer Nachricht zurück. Diese Seite listet jeden Status auf, zeigt den Fehler-Body jedes API-Formats und sagt, welche Fehler sich zum erneuten Senden lohnen.

Die SDKs lösen ein Fehlerobjekt aus, das den Statuscode und die Felder des Bodys enthält. Diese Anfrage nennt ein Modell, das nicht existiert:

import openai
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.shannon-ai.com/v1",
)

try:
    client.chat.completions.create(
        model="no-such-model",
        messages=[{"role": "user", "content": "Hello"}],
    )
except openai.APIStatusError as error:
    print(error.status_code)                           # 400
    print(error.type)                                  # invalid_request_error
    print(error.body["message"])                       # unknown model: no-such-model
    print(error.response.headers.get("x-request-id"))  # the id of this request

Sie gibt den Status 400 und diesen Body zurück:

400 JSON
{
  "error": {
    "type": "invalid_request_error",
    "message": "unknown model: no-such-model"
  }
}

Fehler-Body

Es gibt zwei Bodys. /v1/messages antwortet im Anthropic-Format; jeder andere Endpunkt antwortet im OpenAI-Format. In beiden stehen die Details in error.type und error.message, sodass ein Parser für alle Endpunkte genügt.

401 OpenAI-Format
{
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key",
    "code": "invalid_api_key",
    "param": null
  }
}
401 Anthropic-Format
{
  "type": "error",
  "error": {
    "type": "authentication_error",
    "message": "Invalid API key"
  }
}
Feld Typ Beschreibung
error.type string Die Art des Fehlers. Siehe Fehlertypen weiter unten.
error.message string Ein Satz für Menschen. Die Texte in den Tabellen unten sind bis auf ihre variablen Teile stabil, die als <id>, <n> oder … dargestellt sind.
error.code string | null Bei einigen Fehlern im OpenAI-Format vorhanden: invalid_api_key bei 401, request_too_large bei 413, context_length_exceeded, wenn eine Konversation zu lang ist, sonst null oder nicht vorhanden. Entscheiden Sie zuerst anhand von Status und error.type und behandeln Sie code als Zusatz.
error.param null Bei denselben Fehlern vorhanden wie code. Immer null.
type string Nur im Anthropic-Format. Immer error.

Fehlertypen

Typ Status Beschreibung
invalid_request_error 400, 413, 415, 422 Die Anfrage selbst ist falsch: ein Feld, der Body, die Modell-ID oder ein Input, den das Modell nicht annimmt. Ändern Sie die Anfrage, bevor Sie sie erneut senden.
authentication_error 401 Der API-Key fehlt, ist unbekannt oder widerrufen.
not_found_error 404 Der Pfad existiert nicht.
rate_limit_error 429 Das Guthaben deckt die Anfrage nicht, der Flood-Schutz hat sie gestoppt oder das Modell ist ausgelastet. Die Nachricht sagt, was zutrifft.
api_error 500, 502, 503, 504 Die Anfrage war in Ordnung, und der Fehler liegt auf unserer Seite. Senden Sie sie erneut.
server_error 500 Die Anfrage war in Ordnung, und der Fehler liegt auf unserer Seite. Senden Sie sie erneut.

Statuscodes

Status Typ Nachricht Wann
400 invalid_request_error Failed to parse the request body as JSON: … Der Body ist kein gültiges JSON.
400 invalid_request_error unknown model: <id> model ist keine veröffentlichte ID. Bei /v1/responses auch, wenn model fehlt.
400 invalid_request_error No user message provided Shannon-Stufen: Die Anfrage enthält keinen Nutzertext.
400 invalid_request_error <id> does not accept image input Ein Bild wurde an ein gehostetes Open-Weight-Modell ohne Bild-Input gesendet.
400 invalid_request_error audio and video input are not supported by any hosted model Ein Audio- oder Videoteil wurde an ein gehostetes Open-Weight-Modell gesendet.
400 invalid_request_error <id> does not accept response_format Strukturierte Ausgabe wurde von einem gehosteten Open-Weight-Modell verlangt, das sie nicht hat.
400 invalid_request_error <id> does not accept response_format json_schema; use json_object Ein JSON-Schema wurde an ein gehostetes Open-Weight-Modell gesendet, das nur json_object annimmt.
400 invalid_request_error unknown reasoning effort '<value>'; expected off, low, medium or high Der Reasoning-Aufwand ist keiner der aufgeführten Werte. Gehostete Open-Weight-Modelle.
400 invalid_request_error count_tokens is available for the hosted open models; unknown model: <id> Das Token-Zählen wurde für ein Modell außerhalb der gehosteten Open-Weight-Modelle angefordert.
401 authentication_error Missing authentication Es wurde kein API-Key gesendet.
401 authentication_error Invalid API key Der Key ist unbekannt, wurde durch einen neueren ersetzt oder wurde widerrufen.
404 not_found_error Not Found Der Pfad existiert nicht, zum Beispiel /v1/embeddings.
405 api_error Method Not Allowed Der Pfad existiert, aber nicht mit dieser HTTP-Methode.
413 invalid_request_error Failed to buffer the request body: … Der Request-Body ist größer als 32 MiB.
415 invalid_request_error Expected request with `Content-Type: application/json` Der Header Content-Type fehlt oder ist nicht application/json.
422 invalid_request_error Failed to deserialize the JSON body into the target type: … Ein erforderliches Feld fehlt, etwa messages, oder ein Feld hat den falschen JSON-Typ.
429 rate_limit_error Quota exceeded. Upgrade your plan at shannon-ai.com/plan Das Output-Limit der Anfrage ist größer als das, was von Ihrem Guthaben übrig ist.
429 rate_limit_error Too many requests. Retry in <n>s. Flood-Schutz: mehr als 120 Anfragen in einer Minute auf Ihrem Konto. <n> ist die Anzahl Sekunden bis zum Ende der Minute.
429 rate_limit_error Shannon Coder call quota reached. Upgrade your plan at shannon-ai.com/plan shannon-coder-1 bei /v1/chat/completions und /v1/messages: Die Shannon-Coder-Aufrufe Ihres Plans für das aktuelle 4-Stunden-Fenster sind aufgebraucht.
429 rate_limit_error Shannon routes are temporarily busy. Please retry. Das Modell ist im Moment ausgelastet.
500 server_error The model backend failed to answer. Please retry. Das Modell hat keine Antwort erzeugt.
500 server_error An internal error occurred. Please retry. Ein interner Fehler bei der Vorbereitung der Anfrage.
502 api_error The model backend failed to answer. Please retry. Das Modell hat keine Antwort erzeugt. Shannon-3-Familie und gehostete Open-Weight-Modelle.
503 api_error Could not verify your quota right now. Please retry. Ihr Guthaben konnte im Moment nicht gelesen werden.
503 api_error token counting is temporarily unavailable for this model Das Token-Zählen ist für dieses Modell im Moment nicht verfügbar.
504 api_error upstream timed out Ein gehostetes Open-Weight-Modell hat bei einer nicht gestreamten Anfrage länger als das Zeitlimit gebraucht.

Die Prüfungen laufen in dieser Reihenfolge: API-Key, Request-Body, Modell-ID, Flood-Schutz, Guthaben. Eine Anfrage mit falschem Key und falschem Body gibt daher 401 zurück. Eine Anfrage, die mit einem 4xx-Status abgelehnt wird, wird nicht berechnet.

Guthaben und Flood-Schutz

Jede Anfrage wird gleich bedient: Es gibt keine Ratenstufen und kein separates API-Kontingent. Zwei Dinge können trotzdem mit 429 antworten, beide mit dem Typ rate_limit_error. Die Nachricht unterscheidet sie.

Guthaben

Ihr Guthaben besteht aus dem heutigen Plan-Kontingent, das um 00:00 UTC zurückgesetzt wird, und danach aus Ihrem gekauften Guthaben. Chat und API ziehen vom selben Guthaben ab.

Jede Anfrage legt zuerst ihr Output-Limit zurück: max_tokens oder bei /v1/responses max_output_tokens, 4,096, wenn Sie keines von beiden senden. Ist die Antwort vollständig, wird der zurückgelegte Betrag durch das ersetzt, was die Anfrage verbraucht hat. Passt der Betrag nicht in das verbleibende Guthaben, gibt die Anfrage Quota exceeded zurück, bevor das Modell startet.

Anfragen, die gleichzeitig laufen, legen jeweils ihren eigenen Betrag zurück. Viele parallele Anfragen mit hohem max_tokens können das Guthaben daher kurzzeitig aufbrauchen, auch wenn jede Antwort kurz ist. Ein niedrigeres max_tokens legt weniger zurück.

Flood-Schutz

Der Flood-Schutz erlaubt 120 Anfragen pro Minute und Konto. Er zählt das Konto, nicht den Key, über /v1/chat/completions, /v1/responses und /v1/messages zusammen. Die Minute beginnt mit Ihrer ersten Anfrage.

Anfrage Nummer 121 innerhalb dieser Minute gibt Too many requests. Retry in <n>s. zurück und kostet nichts. Abgelehnte Anfragen zählen ebenfalls, daher bleibt ein Client, der ohne Wartezeit erneut sendet, abgelehnt, bis die Minute vorbei ist. Warten Sie die <n> Sekunden aus der Nachricht.

Parallel gesendete Anfragen werden nicht deshalb abgelehnt, weil sie parallel sind. Sie warten in der Schlange und werden der Reihe nach beantwortet.

GET /v1/models und die Endpunkte zum Token-Zählen werden nicht mitgezählt.

Mehr zu Limits und Guthaben und dazu, wo Sie Ihr eigenes Guthaben und Ihre Nutzung sehen: Limits und Guthaben Keys & Nutzung

Was wiederholt werden sollte

Senden Sie eine Anfrage nur dann erneut, wenn dieselbe Anfrage gelingen kann. Die OpenAI- und Anthropic-SDKs wiederholen Antworten mit 429 und 5xx bereits von selbst zweimal; setzen Sie max_retries (maxRetries in JavaScript), um das zu ändern.

Fehler Erneut senden? Wie
400, 404, 405, 413, 415, 422 Nein. Korrigieren Sie zuerst die Anfrage. Die Nachricht nennt das Feld, das Modell oder den Input, der falsch ist.
401 Nein. Verwenden Sie einen gültigen Key. Erstellen oder ersetzen Sie den Key auf der Seite Keys & Nutzung.
429 Too many requests Ja, nach der Wartezeit. Warten Sie die Anzahl Sekunden aus der Nachricht und senden Sie dann dieselbe Anfrage.
429 Quota exceeded Nicht so, wie sie ist. Senken Sie max_tokens, warten Sie auf das tägliche Zurücksetzen um 00:00 UTC oder laden Sie Guthaben auf.
429 Shannon Coder call quota reached Ja, im nächsten Fenster. Die Fenster beginnen alle 4 Stunden ab 00:00 UTC. Ein anderes Modell antwortet sofort.
429 … temporarily busy Ja. Warten Sie einige Sekunden, bei jedem weiteren Versuch länger.
500, 502, 503 Ja. Warten Sie 1 Sekunde, dann 2, 4 und 8. Hören Sie nach einigen Versuchen auf und melden Sie die Request-ID.
504 Ja. Senden Sie sie mit stream auf true: Das Zeitlimit gilt für Antworten, die nicht gestreamt werden.

Eine Retry-Schleife, die dieser Tabelle folgt:

import re
import time

import openai
from openai import OpenAI

# max_retries=0: this loop does the retrying, the SDK does not add its own.
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://api.shannon-ai.com/v1", max_retries=0)


def create_with_retry(attempts=5, **request):
    for attempt in range(attempts):
        try:
            return client.chat.completions.create(**request)
        except openai.RateLimitError as error:
            text = str(error)
            flood = re.search(r"Retry in (\d+)s", text)
            if flood:
                time.sleep(int(flood.group(1)))   # flood protection: wait out the minute
            elif "temporarily busy" in text:
                time.sleep(2 ** attempt)
            else:
                raise                             # balance: a wait of seconds does not help
        except (openai.InternalServerError, openai.APIConnectionError):
            time.sleep(2 ** attempt)              # 1, 2, 4, 8 seconds
    raise RuntimeError("the request failed after all attempts")


response = create_with_retry(
    model="shannon-3",
    messages=[{"role": "user", "content": "Hello"}],
)
print(response.choices[0].message.content)

Fehler innerhalb eines Streams

Ein Stream hat ab seinem ersten Byte den Status 200. Ein Fehler danach trifft als Event innerhalb des Streams ein: ein Chunk mit einem Member error bei /v1/chat/completions, ein error-Event bei /v1/messages, ein response.failed- oder error-Event bei /v1/responses. Die abschließenden Events des Streams folgen trotzdem. Behandeln Sie eine solche Antwort als fehlgeschlagen und senden Sie die Anfrage erneut, wie bei einem 5xx-Status.

Eine Konversation, die länger als das Kontextfenster des Modells ist, wird auf diese Weise gemeldet, mit dem Typ invalid_request_error und dem Code context_length_exceeded. Kürzen Sie die Konversation, bevor Sie sie erneut senden.

Die genauen Frames sind beim Streaming beschrieben. Streaming

Request-IDs

Jede Antwort, auch bei Fehlern, hat einen Header x-request-id. Er ist der Wert, den Sie in Ihrem eigenen Header x-request-id gesendet haben, oder 12 hexadezimale Zeichen, wenn Sie keinen gesendet haben. Protokollieren Sie ihn und nennen Sie ihn, wenn Sie Hilfe zu einer Anfrage erbitten.