HiAPI
Blog

Tutoriel

HiAPI tâche renvoie TASK_FAILED : causes et méthodes de correction

Comprendre le retour d'une tâche en état terminal, corriger chaque cause une par une, et distinguer les vrais échecs des 4xx et des timeouts.

Oct 22, 2026
HiAPI tâche renvoie TASK_FAILED : causes et méthodes de correction

Lorsque vous soumettez une tâche asynchrone à l'API de tâches HiAPI, une soumission réussie renvoie HTTP 200 et un taskId. La tâche s'exécute ensuite en arrière-plan ; lorsque vous l'interrogez, elle peut se terminer par l'état terminal fail. L'interrogation renvoie alors approximativement ceci — notez que l'appel HTTP lui-même reste un 200 :

{
  "code": 200,
  "data": {
    "taskId": "tk-hiapi-01M4RK...",
    "model": "seedream-5.0-lite/image-to-image",
    "status": "fail",
    "error": { "code": "TASK_FAILED", "message": "task failed" },
    "created": 1791827316,
    "completed": 1791827352,
    "storage": "temp"
  },
  "message": "success"
}

C'est ce que l'on appelle communément « l'erreur TASK_FAILED » : la requête a été acceptée, la tâche a tourné, mais elle n'a finalement pas réussi. Ce n'est pas une erreur HTTP 4xx, et ce n'est pas non plus un timeout. Cet article vous apprend à lire ce retour et à corriger chaque cause une par une.

Commençons par clarifier : TASK_FAILED n'est pas un code de statut HTTP

Le point le plus important à comprendre :

  • Le code de statut HTTP de l'appel d'interrogation est 200, et le corps de la réponse affiche même "message": "success" — cela signifie seulement que l'appel API a réussi, pas que votre tâche a réussi.
  • "status": "fail" (dans data) est le seul critère pour juger de l'échec d'une tâche. Pour une tâche terminée, data.status ne peut valoir que "success" ou "fail".
  • "TASK_FAILED" est la valeur de data.error.code, et non le status. Certains échecs comportent un code plus spécifique et un message plus utile (voir ci-dessous).

Il faut donc toujours interroger GET /v1/tasks/{taskId} et se baser sur data.status pour brancher, et ne jamais juger du succès ou de l'échec uniquement d'après le code de statut HTTP.

Localiser la cause dans le détail de la tâche

Une fois le retour terminal obtenu, lisez les champs data dans cet ordre :

  1. Regardez d'abord data.status — c'est seulement si c'est "fail" qu'il s'agit d'un échec de tâche.
  2. Lisez ensuite data.error.code — c'est la catégorie d'erreur exploitable par la machine (comme TASK_FAILED, INVALID_REQUEST, CONTENT_POLICY_VIOLATION).
  3. Lisez enfin data.error.message — c'est une explication destinée aux humains, qui indique généralement directement la cause (par exemple, une URL d'entrée impossible à récupérer).

error.code détermine essentiellement si cet échec « peut être résolu par une nouvelle tentative » : le TASK_FAILED générique (message le plus souvent "task failed") est souvent un problème transitoire, donc réessayable ; ceux avec un code explicite (comme INVALID_REQUEST, CONTENT_POLICY_VIOLATION) sont des échecs déterministes : sans modifier l'entrée, réessayer autant de fois que vous voulez donnera le même résultat.

Causes fréquentes d'un fail terminal

Classées globalement de la plus fréquente à la moins fréquente.

1. URL d'image / vidéo d'entrée inaccessible ou non publique

C'est la cause la plus fréquente pour les tâches image-vers-image et image/vidéo-vers-vidéo. Si votre input référence une URL que la plateforme ne peut pas récupérer, la tâche sera acceptée mais échouera à l'exécution. Un vrai retour terminal :

"error": {
  "code": "INVALID_REQUEST",
  "message": "The image URL could not be downloaded. Please provide a reachable public HTTP(S) URL and try again."
}

Ici le message est déjà très clair. D'autres modèles exposent la même cause racine sous la forme générique TASK_FAILED / "task failed".

Correction : hébergez l'entrée sur une URL HTTPS accessible publiquement, et vérifiez-la avant la soumission :

curl -I "https://your-host.example.com/input.png"
# 必须返回 200 且是直链媒体 content-type(image/* 或 video/*)
# 不能是 401/403/404,也不能是一个 HTML 页面

Les URL présignées expirées, les adresses localhost / réseau interne, et les liens nécessitant une connexion pour s'ouvrir sont les pièges les plus courants. Il s'agit d'échecs déterministes — tant que l'URL n'est pas corrigée, réessayer ne fera que relancer une tâche vouée à l'échec.

2. Échec transitoire ou d'échec de génération en amont

Il arrive qu'une tâche au format parfaitement correct échoue avec le error.code: "TASK_FAILED" générique et message: "task failed", sans plus de détails. C'est le plus souvent une instabilité transitoire.

Correction : réessayez une ou deux fois. Si cela échoue de façon répétée avec la même entrée, simplifiez l'entrée (raccourcir le prompt, retirer les champs optionnels) puis relancez, afin de réduire le périmètre du déclencheur.

3. Contenu bloqué par la politique de sécurité

Si le prompt ou l'image d'entrée enfreint la politique de sécurité du contenu de la plateforme, la tâche se termine par une erreur de politique déterministe, avec data.error.code égal à CONTENT_POLICY_VIOLATION.

Correction : il s'agit d'un échec permanent, réessayer ne sert à rien. Ajustez le prompt et les ressources d'entrée, retirez le contenu non conforme, puis soumettez à nouveau.

4. Un paramètre refusé par le modèle seulement à l'exécution

La grande majorité des paramètres invalides sont bloqués dès la soumission par un HTTP 400 (vous n'obtenez même pas de taskId) — voir la section suivante. Il arrive occasionnellement qu'une option légale en soi mais non supportée par le modèle lorsqu'elle est combinée ne soit refusée qu'à l'exécution de la tâche, aboutissant à data.status: "fail". error.message indiquera quelle option est en cause.

Correction : lisez data.error.message, puis consultez la page du modèle pour vérifier les entrées supportées (par exemple la page du modèle GPT Image 2), et supprimez ou corrigez le champ qu'il désigne.

Comment distinguer TASK_FAILED, les 4xx et les timeouts

Trois situations totalement différentes sont toutes communément décrites comme « un échec », mais les corrections diffèrent :

Ce que vous voyez Signification Où corriger
Le POST renvoie un code non 2xx (400/401/402/429) et aucun taskId La requête a été rejetée, aucune tâche n'a démarré Corriger la requête / la clé / le solde (voir les liens ci-dessous)
Le POST renvoie 200 + taskId, l'interrogation affiche data.status: "fail" TASK_FAILED — la tâche a tourné et a échoué Lire data.error.message (cet article)
Le POST renvoie 200 + taskId, l'interrogation dépasse votre échéance et reste dans un état non terminal (comme handling) Timeout, pas un échec Continuer d'interroger / augmenter le timeout / réessayer

Si vous n'avez pas obtenu de taskId du tout, ce n'est pas un TASK_FAILED, mais une erreur de requête :

L'échec d'authentification est rejeté au niveau de la requête, avec un retour HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}} ; aucune tâche n'est créée, donc il ne peut pas y avoir de TASK_FAILED.

Checklist de correction

  1. Interrogez la tâche, ne vous fiez pas au seul POST. La soumission vous indique seulement que la tâche est en file. Appelez GET /v1/tasks/{taskId} et regardez data.status.
  2. Confirmez qu'il s'agit d'un vrai échec : data.status == "fail" (le code HTTP reste 200).
  3. Lisez data.error.code et data.error.message. Le message est votre signal prioritaire.
  4. Si l'URL d'entrée est mentionnée : remplacez l'URL par une adresse accessible publiquement, vérifiez avec curl -I (200 + content-type média direct).
  5. Si le message est générique ("task failed") : traitez-le comme un problème transitoire et réessayez ; si l'échec persiste, simplifiez l'entrée.
  6. Si c'est une erreur déterministe comme CONTENT_POLICY_VIOLATION : c'est un échec permanent, ne réessayez pas automatiquement — seule une modification de l'entrée sera utile.
  7. Vérifiez que l'id du modèle figure actuellement dans GET /v1/models et correspond exactement à celui que vous envoyez. Un id inconnu échoue à la soumission avec 400 MODEL_UNAVAILABLE, et non en fail terminal.
  8. Aucun taskId du tout ? Ce n'est alors pas un TASK_FAILED — reportez-vous au guide d'erreur de requête correspondant ci-dessus.

Exemple de vérification minimal

Avant d'enquêter sur une tâche précise, confirmez d'abord votre clé et la connectivité avec une requête propre. Appelez l'API de tâches unifiée POST https://api.hiapi.ai/v1/tasks, avec l'id de modèle en id brut (sans suffixe d'endpoint) :

# 1)提交——预期 HTTP 200 + 一个 taskId
curl -s https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-image-2","input":{"prompt":"a red bicycle on a white background","aspect_ratio":"1:1"}}'
# -> {"code":200,"data":{"taskId":"tk-hiapi-..."},"message":"success"}

# 2)轮询——换上你拿到的 taskId
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxxxxxx \
  -H "Authorization: Bearer sk-YOUR_KEY"
# -> 运行中 data.status 是 "handling",随后变为 "success" 或 "fail"

Si l'étape 1 renvoie 200 et un taskId, cela signifie que votre clé et l'interface fonctionnent correctement ; tout échec est alors un problème de tâche individuelle, et non d'intégration. Si l'étape 1 renvoie 401, votre clé est incorrecte — gérez-la dans la console HiAPI. Attention : cet exemple soumet une vraie génération et sera facturé.

À propos de la facturation : ne payez pas à répétition pour des tâches vouées à l'échec

Pour savoir si une tâche échouée est facturée et comment fonctionnent la pré-autorisation et le remboursement, voir Les requêtes échouées de HiAPI sont-elles facturées ?. Deux points essentiels :

  • Ne réessayez pas automatiquement à l'aveugle les échecs déterministes. Pour CONTENT_POLICY_VIOLATION, les URL inaccessibles et autres cas similaires, chaque nouvelle tentative est une nouvelle tâche, potentiellement facturée. Modifiez d'abord l'entrée, ne laissez pas la logique de retry tourner à vide et brûler de l'argent.
  • Vérifiez l'URL d'entrée avec curl -I avant la soumission. Une vérification HEAD est gratuite, alors qu'une tâche vouée à l'échec à cause d'un lien cassé peut être payante.

FAQ

TASK_FAILED est-il un code de statut HTTP ? Non. L'appel HTTP renvoie 200. TASK_FAILED est la valeur de data.error.code dans le retour terminal, et le data.status de ce retour est "fail".

data.status est "fail", mais je cherche "TASK_FAILED" — que regarder au juste ? Chacun à son emplacement. Pour une tâche terminée, data.status vaut toujours "success" ou "fail" ; "TASK_FAILED" est un data.error.code générique, et une tâche en échec peut aussi comporter un code plus spécifique (comme INVALID_REQUEST, CONTENT_POLICY_VIOLATION) et un message exploitable.

Quels TASK_FAILED peuvent être réessayés, et lesquels non ? Le "task failed" générique (sans plus de détails) est souvent un problème transitoire, réessayable une ou deux fois ; les échecs déterministes avec un code explicite (mauvaise URL → INVALID_REQUEST, contenu non conforme → CONTENT_POLICY_VIOLATION, paramètre refusé par le modèle) ne servent à rien à réessayer, il faut modifier l'entrée.

Ma tâche reste bloquée sur handling, sans échouer ni réussir. C'est un timeout, pas un échec. Continuez d'interroger ou augmentez le timeout du client ; voir Timeout de tâche HiAPI et erreur 504.

Je reçois 400 / 401 / 402 au lieu d'un taskId. Ce sont des requêtes rejetées — aucune tâche n'a été créée, donc il n'y a pas d'« échec ». Utilisez les guides liés ci-dessus pour corriger la requête, la clé ou le solde.

Les tâches échouées sont-elles facturées ? Voir Les requêtes échouées de HiAPI sont-elles facturées ? pour comprendre comment la pré-autorisation et le remboursement sont traités en cas d'échec.

Comment confirmer qu'une URL d'entrée est mauvaise ? Lisez data.error.message. Un problème d'URL indique généralement que l'image ou la vidéo ne peut pas être téléchargée ; vérifiez avec curl -I que le lien renvoie 200 et qu'il s'agit d'un fichier média direct.

Articles similaires

Voir tous les articles →

Commencez avec des artefacts IA persistants

Obtenez votre clé API et appelez des modèles d'image, de vidéo et d'audio via une API unique basée sur les tasks.

Lire la documentation de l'API