Documentation › Erreurs
Erreurs
Un refus porte un code stable, un message en français et, quand c’est possible, une piste (hint) qui dit quoi faire. Le code ne change pas : c’est lui qu’un agent teste. La piste se suit, elle ne se contourne pas.
La forme d’un refus
Par MCP, un refus est un résultat d’outil marqué isError, avec un texte lisible : le message, le code entre parenthèses, puis la piste après une flèche.
Doublon : un message de agent@exemple.fr à nadia.morel@exemple.com est déjà parti (créé lundi 12 octobre à 10 h 14). Règle de l’espace : un seul premier message par destinataire et par boîte en 30 jours. (code duplicate_recipient) → Pour relancer, répondez dans le fil thr_b81f4c6a2d9e47035c1a8e6f0b4d2c97 avec reply_to_thread (une réponse dans un fil n’est pas un doublon).
En HTTP (POST /v1/{opération}), le même refus est un statut HTTP et un corps JSON :
{
"error": {
"code": "duplicate_recipient",
"message": "Doublon : un message de agent@exemple.fr à nadia.morel@exemple.com est déjà parti (créé lundi 12 octobre à 10 h 14). Règle de l’espace : un seul premier message par destinataire et par boîte en 30 jours.",
"hint": "Pour relancer, répondez dans le fil thr_b81f4c6a2d9e47035c1a8e6f0b4d2c97 avec reply_to_thread (une réponse dans un fil n’est pas un doublon)."
}
}Ce qui n’est pas une erreur
Un message retenu n’est pas refusé. La réponse est un succès, et elle dit ce qu’il attend.
| Situation | Ce que rend le serveur | Que faire |
|---|---|---|
| Quota du jour de la boîte atteint | Le message est en file (queued), avec le départ au plus tôt. | Rien. Ne le renvoyez pas. |
| Envoi hors des heures ouvrées | Le message est en file, avec le départ au plus tôt. | Rien. |
| Validation humaine demandée | Le message est un brouillon (draft). | Attendre un humain : approve_message demande la permission approve. |
Même idempotency_key, même contenu | Le message déjà créé, avec replayed: true. | Rien : rien de nouveau n’a été créé. |
Règles d’envoi
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
space_unverified | 403 | L’espace n’est pas vérifié : ses boîtes reçoivent, mais n’envoient pas. | Demander à l’humain le code à 6 chiffres, puis appeler verify. S’il n’a rien reçu : attach_human. |
trial_limit | 429 | La limite d’essai du domaine commun est atteinte. | Attendre le palier suivant, donné par la piste. Réécrire à un destinataire déjà compté reste possible. Pour sortir des limites : add_domain. |
recipient_suppressed | 422 | Le destinataire est bloqué : désinscription, plainte, adresse morte ou blocage manuel. | Ne plus écrire à cette adresse, depuis aucune boîte. |
duplicate_recipient | 409 | Cette boîte a déjà écrit un premier message à ce destinataire dans les 30 derniers jours. | Répondre dans le fil donné par la piste, avec reply_to_thread. |
key_daily_cap | 429 | Le plafond de messages par jour de la clé est atteint. | Reprendre le lendemain, à partir de 0 h, heure de Paris. |
inbox_suspended | 409 | Le coupe-circuit a suspendu la boîte. La raison est dans le message. | Vérifier la liste de destinataires. La reprise est manuelle, par un administrateur de Subagent. |
unresolved_placeholder | 422 | Un champ entre doubles accolades est resté dans le sujet ou le texte. | Remplacer chaque champ par sa valeur. Seul {{unsubscribe_url}} est accepté. |
idempotency_conflict | 409 | La même idempotency_key a déjà servi pour un contenu différent. | Même message : réutiliser la clé telle quelle. Nouveau message : en prendre une nouvelle. |
test_recipient_not_allowed | 422 | Un envoi de test (test: true) vise une adresse hors de l’espace. | Envoyer le test à l’e-mail de l’humain de l’espace ou à une autre de vos boîtes. Pour écrire à ce destinataire : retirer test. |
queue_full | 429 | La file de la boîte est pleine : trop de brouillons et de messages en attente (dix fois son quota maximal du jour). | Laisser partir les messages en attente, ou annuler ceux qui ne servent plus avec cancel_message. |
Inscription et vérification
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
signups_closed | 403 | Les inscriptions sont fermées sur ce serveur. | Demander une clé ou une invitation à contact@subagent.fr. |
invitation_required | 403 | Bêta sur invitation : l’e-mail de l’humain n’est pas invité. | Demander une invitation pour cette adresse. En attendant, sign_up sans human_email ouvre une boîte qui reçoit. |
signup_rate_limited | 429 | Trop d’inscriptions en 24 heures, depuis la même adresse ou sur tout le service, ou trop de codes envoyés au même e-mail. | Réessayer plus tard. Une clé déjà obtenue se réutilise. |
username_taken | 409 | Ce nom de boîte est déjà pris. | Choisir un autre username. |
reserved_username | 422 | Ce nom est réservé : adresse de service, ou nom réservé sur le domaine commun. | Choisir le nom de l’agent, d’une personne ou d’une fonction. |
human_email_not_allowed | 422 | L’adresse donnée n’est pas celle d’une personne : boîte Subagent, ou domaine d’exemple. | Donner l’adresse personnelle ou professionnelle de l’humain. |
no_pending_code | 409 | Aucun code n’attend pour cet espace. | Appeler attach_human avec l’e-mail de l’humain. |
invalid_code | 422 | Le code est incorrect. Le message donne le nombre d’essais. | Redemander le code du dernier e-mail reçu : un code plus ancien ne vaut plus. |
code_expired | 409 | Le code a plus de 24 heures. | Appeler attach_human avec le même e-mail. |
too_many_attempts | 429 | Dix essais ont échoué : le code ne vaut plus. | Appeler attach_human pour recevoir un nouveau code. |
code_too_soon | 429 | Un code vient d’être envoyé. | Attendre le nombre de secondes donné par la piste. |
code_limit | 429 | Cinq codes ont déjà été envoyés pour cet espace. | Donner à verify un code encore valable. Sinon, se réinscrire sous un autre nom. |
code_not_sent | 502 | L’e-mail du code n’a pas pu partir. | Rien n’a changé : rappeler attach_human dans un instant. |
human_change_limit | 409 | L’e-mail de l’humain a déjà été remplacé deux fois. | Rappeler attach_human avec l’adresse déjà rattachée. |
already_verified | 409 | L’espace est déjà vérifié. | Rien : l’envoi est ouvert. |
not_signed_up | 409 | L’espace n’a pas été ouvert par sign_up : il n’a pas de code. | Rien à vérifier. |
Boîtes
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
address_taken | 409 | L’adresse est déjà une boîte. | Choisir un autre username. |
inbox_limit | 409 | Le plafond de boîtes de l’espace est atteint. | Supprimer une boîte inutile avec delete_inbox. |
inbox_creation_limit | 429 | Trop de boîtes créées en 7 jours pour l’espace. Les boîtes supprimées comptent. | Garder ses boîtes plutôt que les supprimer et les recréer. Pour un besoin réel, écrire à contact@subagent.fr. |
domain_not_allowed | 422 | Le domaine demandé n’est pas un domaine d’envoi de l’espace. Ou, pour add_domain, c’est un domaine de Subagent. | Prendre un des domaines donnés par la piste, ou enregistrer un domaine dont vous gérez le DNS. |
no_sending_domain | 409 | L’espace n’a aucun domaine d’envoi. | Prévenir un administrateur de Subagent. |
provisioning_failed | 502 | Le serveur de messagerie n’a pas créé la boîte, ou n’a pas pris le domaine. | Réessayer dans un instant. Rien n’est perdu. |
Domaines
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
domain_exists | 409 | Le domaine est déjà enregistré pour cet espace. | Appeler list_domains : il donne ses enregistrements DNS et son état. |
domain_taken | 409 | Le domaine est déjà enregistré par un autre espace. | Enregistrer un sous-domaine, ou demander à un administrateur de Subagent de le libérer. |
domain_limit | 409 | Le plafond de cinq domaines par espace est atteint. | Retirer un domaine inutile avec remove_domain. |
domain_in_use | 409 | Des boîtes de l’espace vivent encore sur le domaine à retirer. | Supprimer d’abord ces boîtes avec delete_inbox. |
domain_not_verified | 409 | Le domaine de la boîte n’est pas encore vérifié. | Publier ses enregistrements DNS, puis appeler verify_domain. |
domain_suspended | 409 | Un enregistrement DNS exigé a disparu : le domaine est suspendu, ses boîtes n’envoient plus. | Remettre les enregistrements en place (list_domains les donne), puis appeler verify_domain. |
dns_unavailable | 503 | La résolution DNS a échoué : rien n’a pu être contrôlé. | Réessayer dans un instant. L’état du domaine n’a pas changé. |
Brouillons et messages
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
not_draft | 409 | Le message n’est pas, ou n’est plus, un brouillon. | Relire son statut avec get_message. |
draft_changed | 409 | Le brouillon a été modifié depuis sa lecture : la revision donnée n’est plus la sienne. | Relire le brouillon avec list_drafts, puis valider la version lue. |
not_cancellable | 409 | Le message ne s’annule plus : il est parti, ou déjà annulé. | Rien : un message parti ne se rappelle pas. |
Liste de blocage
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
public_mail_domain | 422 | Une messagerie publique (gmail.com…) ne se bloque pas en entier, et ne s’enregistre pas comme domaine. | Bloquer les adresses une à une. Enregistrer un domaine dont vous gérez le DNS. |
suppression_protected | 409 | Une désinscription, une plainte ou une adresse morte ne se lèvent pas par l’outil. | Rien. Seule la personne peut demander, par écrit, la levée d’une désinscription. |
Accès et requêtes
| Code | HTTP | Ce qui s’est passé | Que faire |
|---|---|---|---|
unauthorized | 401 | La clé est absente, inconnue ou révoquée. | Envoyer l’en-tête Authorization: Bearer sak_…. Pas encore de clé : sign_up. |
origin_refused | 403 | L’appel vient de la page web d’un autre site (en-tête Origin). | Appeler l’API depuis votre agent ou votre serveur, sans en-tête Origin. |
forbidden | 403 | La clé ne porte pas la permission que l’outil demande. | Pour approve : la validation revient à un humain. Sinon, demander une clé qui porte la permission. |
not_found | 404 | L’objet n’existe pas pour cette clé. | Vérifier l’identifiant : il vient de list_inboxes, list_threads, get_thread ou list_drafts. |
invalid_argument | 400 | Un paramètre manque, est inconnu ou mal formé. | Lire le message : il nomme le paramètre. La piste liste les paramètres acceptés. |
unknown_operation | 404 | L’opération demandée n’existe pas. | Lire la liste des outils (tools/list, /llms.txt ou /openapi.json). |
payload_too_large | 413 | Le corps de la requête dépasse 1 Mio. | Raccourcir le message. |
rate_limited | 429 | Trop de requêtes en une minute depuis la même adresse (60 sans clé, 600 avec une clé), ou plus de six verify_domain par minute pour un espace. | Attendre le délai donné par l’en-tête Retry-After, puis espacer les appels. |
internal | 500 | Erreur interne du serveur. | Réessayer dans un instant, avec la même idempotency_key. |
encryption_unavailable | 503 | Le serveur n’est pas entièrement configuré. | Prévenir un administrateur de Subagent. |
Les codes portés par un message
Un message qui n’est pas parti garde la raison dans status_code et status_detail. get_message les rend, avec le journal.
status | status_code | Sens |
|---|---|---|
rejected | recipient_suppressed | Le destinataire a été bloqué entre la création et l’envoi. |
rejected | duplicate_recipient | Un autre premier message vers ce destinataire est parti entre-temps. |
cancelled | cancelled_by_key | Annulé par cancel_message. |
cancelled | recipient_unsubscribed | Annulé parce que le destinataire s’est désinscrit. |
cancelled | recipient_suppressed | Annulé parce que le destinataire a été bloqué avec add_suppression. |
cancelled | inbox_deleted | Annulé parce que la boîte a été supprimée. |
failed | smtp_rejected | Le serveur de messagerie a refusé le message. |
failed | policy_rejected | Le serveur du destinataire a refusé le message pour une raison de politique. |
failed | interrupted | L’envoi a été interrompu. Il n’est pas renvoyé automatiquement, pour ne pas risquer un doublon. |
Cette page en Markdown : /docs/erreurs.md
Toute la documentation pour un agent : /llms.txt
Mentions légales · Confidentialité