Hermes hat dich gerade gebeten, eine Browser-Prüfung zu absolvieren? Hier steht, was es mit dem 428-challenge im Free Tier auf sich hat

Es ist zwei Uhr morgens. Dein Cron-Job läuft auf einem Server und nutzt das Free Tier für eine Runde Recherche. Kein Fehler in den Logs – nur ein Link, den jemand ausgegeben hat, und dann schlägt der Job still fehl. Am Morgen liest du ihn und hast keine Ahnung, was dieser Link war, warum er aufgetaucht ist oder ob du darauf klicken solltest.
An deinem Setup ist nichts kaputt. Das Free Tier hat jetzt einfach ein Gate davor. PR #133824, gemergt am 6. Oktober, lehrt Hermes, diesen Pfad richtig zu behandeln – und, wichtiger noch, stellt sicher, dass es niemals wartend dasitzt, wenn niemand da ist, auf den man warten könnte.
Wann das Gate auftaucht
Kostenlose anonyme Inferenz läuft für einen Token-Austausch über POST /api/anonymous/token. Das Portal kann so konfiguriert werden, dass es vor der Ausgabe anonymer Kapazität eine Browser-Prüfung aus ausgewählten IP-Bereichen oder Ländern verlangt. Wenn eine solche Regel greift, antwortet dieser Endpoint mit HTTP 428, dem Code challenge_required und einer portal-URL.
Der wichtige Teil: Das ist eine Policy auf der Portal-Seite, jederzeit anpassbar ohne Hermes-Release. „Es lief letzte Woche noch einwandfrei“ hat also meist nichts mit deiner Maschine zu tun.
Ein Primitiv, drei Schritte
Hermes implementiert dafür genau ein Primitiv namens browser-v1:
- die URL öffnen, die das Portal übergeben hat;
/api/anonymous/challenge/statuspollen, bis sie sich auflöst;- erneut gegen einen Token austauschen.
Alles, was die Seite selbst tut – Bot-Erkennung, Proof of Work im Browser, ein interaktiver Fallback, ihr gesamter Text –, gehört zum Portal und kann sich ändern, ohne dass du irgendetwas aktualisierst. Und die Mint bleibt die Autorität: Hermes entscheidet nie lokal, dass eine Prüfung bestanden wurde.
Der Austausch sendet einen selbstgemeldeten client-Block (surface, version, platform, plus capabilities: ["browser-v1"]) und einen hermes-agent/<version>-User agent.
Wer das Fenster öffnet
Das Verhalten unterscheidet sich je nach Surface, was die Antwort auf „warum habe ich nichts gesehen“ ist:
- Desktop: Dieser Prozess öffnet selbst nichts. Er veröffentlicht den challenge (ein globales Event
free_tier.challenge, plus das Feldchallengeauffree_tier.statusfür einen Client, der sich später verbindet); der Renderer übergibt ihn an den Electron-Main-Prozess, der ihn in einem versteckten, gesandboxten, origin-gepinnten Fenster lädt. Dieses Fenster wird nur gezeigt, wenn die Seite ausdrücklich einen Menschen verlangt. - Terminal: den Link ausgeben und, wenn ein grafischer Browser vorhanden ist, im System-Browser öffnen.
- Das Warten läuft außerhalb der Locks: Der Austausch, der den 428 traf, hat seine Exception bereits aus den
with-Blöcken herausgewickelt, sodass eine langsame Seite nie ein benachbartes Profil oder einen anderen Prozess blockiert. Pro Prozess wird jeweils ein challenge bearbeitet; ein zweiter Thread, der denselben 428 trifft, wartet auf den ersten und tauscht dann einfach erneut aus.
Wann es dich absolut nicht hängen lässt
Die riskantesten Stellen steckten in der ersten Version dieser Arbeit, und ihre Behebung macht den Großteil dessen aus, was dieser PR tut. Es sind alles vertraute Muster:
- Ein gateway wartet nie. Gateways lösen Nous-Credentials synchron aus asynchronem Code auf, sodass ein 428 die Event-Loop bis zu 120 Sekunden blockierte – und niemand sitzt an der Konsole eines Bots, um eine Browser-Prüfung zu bestehen. Die gateway-Surface zeichnet jetzt auf, kündigt an und wirft sofort einen retryable Error.
- Der Proxy-Adapter blockiert das Lock nicht mehr. Er löste Credentials auf, solange er das Lock hielt, auf das jede proxied Anfrage wartet, sodass eine 120-Sekunden-Pause alles blockierte. Jetzt löst er als Background-Caller auf.
- Background-Reader öffnen nie etwas. Keepalive-Ticks und Status-Paints empfangen den challenge, blockieren aber nie, geben nichts aus und öffnen keinen Browser.
- Die stdio-TUI sagt dir endlich Bescheid. Sie behielt stderr des gateway-Kindprozesses früher nur als Log, sodass ein challenge zu einem stillen 120-Sekunden-Hänger ohne Link wurde. Erforderliche Foreground-Challenges werden jetzt über JSON-RPC angekündigt und die TUI gibt den Link aus.
Erforderlich und optional sind verschiedene Dinge
Ein challenge kann auch bei einem erfolgreichen Austausch mit required: false ankommen – der Service misst, statt durchzusetzen. Dieser wird ausschließlich einem Desktop-Client angekündigt (damit ein verstecktes Fenster ihn früh auflösen kann); er wird nie in deinem Browser geöffnet und nichts wartet darauf.
Ein erforderlicher challenge lässt eine interaktive Surface tatsächlich warten: bis zu 120 Sekunden pro Versuch, was den Fall „ein Mensch löst gerade ein Captcha“ begrenzt, ohne eine Anfrage für die vollen zehn Minuten des Tickets zu parken. Eine fehlgeschlagene Ankündigung (etwa ein Problem auf der Standardausgabe) fällt auf das Ausgeben des Links zurück, statt ihn zu verlieren und den Lauf fehlschlagen zu lassen.
Was passiert, wenn er sich nicht auflöst
- Ein challenge, der sich nie auflöst, endet mit retryable Text und einem Fail-Fast-Cooldown statt endlosem Retrying.
- Ein zweites
challenge_requiredwird nicht geloopt – es tritt als retryable Error mit Erklärung zutage. Das ist Absicht: Eine Schleife wäre schlimmer als ein Fehlschlag. - Ein
pow_*-Fehlercode bei einem Nicht-428-Status behält seine ursprüngliche Bedeutung (er wird nicht mehr über jeden Endpoint als retryable Server-Fehler behandelt), sodass Sign-up- und Promotions-Flows unberührt bleiben.
Was du dagegen tun kannst
Wenn deine Maschine unbeaufsichtigt ist (ein Server, ein Container, CI):
- öffne diesen Link in deinem Browser und löse die Prüfung; das Ticket gehört zu diesem Austausch, lass Hermes danach also erneut versuchen.
- wenn das immer wieder passiert, zieh in Betracht, geplante Arbeit über die Kapazität eines angemeldeten Nous-Kontos statt über das anonyme Free Tier laufen zu lassen – der Account-Pfad durchläuft die anonyme Prüfung nicht. Siehe diesen Artikel über die kostenlose Suchroute für die zugehörigen Diagnosen.
- Auf dem Desktop: Tu nichts. Das versteckte Fenster erledigt es im Hintergrund und erscheint nur, wenn du gebraucht wirst.
Die Kurzfassung
Die Prüfung ist kein Bug; sie ist Portal-Policy, die ihre Arbeit tut. Die Verantwortlichkeiten von Hermes sind absichtlich schmal: dir den Link vor die Nase setzen, niemals dort blockieren, wo niemand zuschaut, und nie lokal schlussfolgern, dass eine Prüfung bestanden wurde. Wenn du diese Arbeitsteilung einmal kennst, ist ein Link in deinen Logs ein Fünf-Sekunden-Fix statt eines verlorenen Morgens.
Wenn du lieber überhaupt nicht vom Free Tier abhängen willst, vergleiche fünf kostenlose Suchkanäle.