HiAPI
Blogue

Tutorial

Tarefa HiAPI retorna TASK_FAILED: causas e como corrigir

Entenda o retorno de tarefa em estado terminal, corrija cada tipo de causa e diferencie falhas reais de 4xx e timeouts.

Oct 22, 2026
Tarefa HiAPI retorna TASK_FAILED: causas e como corrigir

Ao enviar uma tarefa assíncrona para a interface de tarefas da HiAPI, um envio bem-sucedido retorna HTTP 200 e um taskId. A tarefa então é executada em segundo plano; quando você a consulta por polling, ela pode terminar no estado terminal fail. Nesse caso, o polling retorna aproximadamente o seguinte — observe que a chamada HTTP em si continua sendo 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"
}

É isso que todos chamam de "erro TASK_FAILED": a requisição foi aceita, a tarefa foi executada e, no final, não teve sucesso. Isso não é um erro HTTP 4xx e também não é um timeout. Este artigo ensina a interpretar esse retorno e corrigir cada tipo de causa.

Primeiro, entenda: TASK_FAILED não é um status code HTTP

O ponto mais importante a entender:

  • O status code HTTP da chamada de polling é 200, e o corpo da resposta até contém "message": "success" — isso apenas indica que a chamada à API teve sucesso, não que sua tarefa teve sucesso.
  • "status": "fail" (dentro de data) é o critério para determinar a falha da tarefa. Para uma tarefa concluída, data.status só pode ser "success" ou "fail".
  • "TASK_FAILED" é o valor de data.error.code, não de status. Algumas falhas vêm com um code mais específico e uma message mais útil (veja abaixo).

Portanto, sempre faça polling em GET /v1/tasks/{taskId} e use data.status como base para ramificação; nunca julgue sucesso ou falha apenas pelo status code HTTP.

Localize a causa nos detalhes da tarefa

Após obter o retorno em estado terminal, leia os campos de data nesta ordem:

  1. Primeiro veja data.status — só é falha de tarefa se for "fail".
  2. Depois leia data.error.code — é a categoria de erro determinável por máquina (como TASK_FAILED, INVALID_REQUEST, CONTENT_POLICY_VIOLATION).
  3. Por fim leia data.error.message — é a descrição para humanos, geralmente apontando diretamente a causa (por exemplo, alguma URL de entrada não pôde ser baixada).

error.code basicamente determina se esta falha "pode ser resolvida com retry": o genérico TASK_FAILED (message geralmente "task failed") costuma ser um problema transitório e pode ser retentado; os com code explícito (como INVALID_REQUEST e CONTENT_POLICY_VIOLATION) são falhas determinísticas — não importa quantas vezes você retente sem alterar a entrada, o resultado será o mesmo.

Causas comuns de fail em estado terminal

Aproximadamente em ordem decrescente de frequência.

1. URL de imagem/vídeo de entrada inacessível ou não pública

Esta é a causa mais comum em tarefas de image-to-image e image/video-to-video. Se seu input referencia uma URL que a plataforma não consegue baixar, a tarefa é aceita mas falha durante a execução. Um retorno real em estado terminal:

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

Aqui a message já explica tudo claramente. Outros modelos expõem a mesma causa raiz como o genérico TASK_FAILED / "task failed".

Correção: hospede a entrada em uma URL HTTPS acessível publicamente e valide antes de enviar:

curl -I "https://your-host.example.com/input.png"
# Deve retornar 200 e content-type de mídia direta (image/* ou video/*)
# Não pode ser 401/403/404, nem uma página HTML

URLs pré-assinadas expiradas, endereços localhost / de rede interna e links que exigem login são as armadilhas mais comuns. Isso é uma falha determinística — se a URL não for corrigida, o retry só vai executar a tarefa em vão mais uma vez.

2. Falha transitória ou de geração no upstream

Às vezes uma tarefa com formato perfeitamente correto falha com o genérico error.code: "TASK_FAILED", message: "task failed", sem mais detalhes. Essas geralmente são oscilações transitórias.

Correção: tente novamente uma ou duas vezes. Se falhar repetidamente com a mesma entrada, simplifique a entrada (encurte o prompt, remova campos opcionais) e execute novamente para reduzir o escopo do gatilho.

3. Conteúdo bloqueado pela política de segurança

Se o prompt ou a imagem de entrada ferir a política de segurança de conteúdo da plataforma, a tarefa termina com um erro determinístico de política, com data.error.code igual a CONTENT_POLICY_VIOLATION.

Correção: esta é uma falha permanente; retry não adianta. Ajuste o prompt e os materiais de entrada, remova o conteúdo violador e envie novamente.

4. Um parâmetro que o modelo só rejeita em tempo de execução

A grande maioria dos parâmetros inválidos é barrada no envio com HTTP 400 (você nem chega a receber o taskId) — veja a próxima seção. Ocasionalmente, alguma opção que é válida isoladamente mas que o modelo não suporta em combinação só é rejeitada durante a execução, resultando em data.status: "fail". A error.message indica qual opção.

Correção: leia data.error.message e consulte a página do modelo para verificar as entradas suportadas por ele (por exemplo, a página do modelo GPT Image 2), removendo ou corrigindo o campo indicado.

Como diferenciar TASK_FAILED, 4xx e timeout

Há três situações completamente diferentes que costumam ser chamadas vagamente de "falhou", mas as correções são distintas:

O que você vê Significado Onde corrigir
POST retorna não-2xx (400/401/402/429) e sem taskId Requisição rejeitada; nenhuma tarefa chegou a rodar Corrija a requisição / key / saldo (veja os links abaixo)
POST retorna 200 + taskId, e o polling mostra data.status: "fail" TASK_FAILED — a tarefa rodou e falhou Leia data.error.message (este artigo)
POST retorna 200 + taskId, e o polling ultrapassa seu deadline permanecendo em estado não terminal (como handling) Timeout, não falha Continue o polling / aumente o timeout / retente

Se você nem recebeu um taskId, então não é TASK_FAILED, mas erro de requisição:

Falhas de autenticação são rejeitadas na camada de requisição, retornando HTTP 401 + {"error":{"code":"permission_denied","type":"hiapi_error","request_id":"..."}}, sem criar tarefa; naturalmente, não há que se falar em TASK_FAILED.

Checklist de correção

  1. Faça polling da tarefa, não confie apenas no POST. O envio só informa que a tarefa entrou na fila. Chame GET /v1/tasks/{taskId} e veja data.status.
  2. Confirme que é falha real: data.status == "fail" (o código HTTP continua sendo 200).
  3. Leia data.error.code e data.error.message. A message é seu principal sinal.
  4. Se mencionar URL de entrada: torne a URL acessível publicamente e valide com curl -I (200 + content-type de mídia direta).
  5. Se a message for genérica ("task failed"): trate como problema transitório e retente; se continuar falhando repetidamente, simplifique a entrada.
  6. Se for erro determinístico como CONTENT_POLICY_VIOLATION: é falha permanente, não faça retry automático — só alterar a entrada resolve.
  7. Confirme se o model id está atualmente em GET /v1/models e é exatamente igual ao que você enviou. Um id desconhecido falha no envio com 400 MODEL_UNAVAILABLE, e não como fail em estado terminal.
  8. Não recebeu taskId nenhum? Então não é TASK_FAILED — vá para o guia correspondente de erro de requisição acima.

Exemplo mínimo de verificação

Antes de investigar uma tarefa específica, faça uma requisição limpa para confirmar sua key e conectividade. Use a interface unificada de tarefas POST https://api.hiapi.ai/v1/tasks, com o model id em id puro (sem sufixo de endpoint):

# 1) Envio — espera-se HTTP 200 + um 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) Polling — substitua pelo taskId recebido
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-xxxxxxxx \
  -H "Authorization: Bearer sk-YOUR_KEY"
# -> em execução, data.status é "handling", depois muda para "success" ou "fail"

Se o passo 1 retornar 200 e taskId, sua key e a interface estão normais, e qualquer falha será problema de uma tarefa individual, não de integração. Se o passo 1 retornar 401, a key está incorreta — gerencie keys no Console HiAPI. Atenção: este exemplo envia uma geração real e gerará custos.

Sobre cobrança: não pague repetidamente por tarefas fadadas a falhar

Para saber se tarefas falhas são cobradas e como funcionam a pré-cobrança e o reembolso, veja Requisições falhas da HiAPI são cobradas?. Dois pontos principais:

  • Não faça retry automático cego em falhas determinísticas. CONTENT_POLICY_VIOLATION, URL inacessível e afins: cada retry é uma nova tarefa e pode ser cobrado. Altere a entrada primeiro; não deixe a lógica de retry girar em falso queimando dinheiro.
  • Valide a URL de entrada com curl -I antes de enviar. Uma verificação HEAD é gratuita, enquanto uma tarefa fadada a falhar por link quebrado pode ser cobrada.

FAQ

TASK_FAILED é um status code HTTP? Não. A chamada HTTP retorna 200. TASK_FAILED é o valor de data.error.code no retorno em estado terminal, e o data.status desse retorno é "fail".

data.status é "fail", mas estou procurando "TASK_FAILED" — afinal, qual olhar? Cada um no seu lugar. Para uma tarefa concluída, data.status é sempre "success" ou "fail"; "TASK_FAILED" é um data.error.code genérico, e tarefas falhas também podem trazer codes mais específicos (como INVALID_REQUEST e CONTENT_POLICY_VIOLATION) e messages acionáveis.

Quais TASK_FAILED podem ser retentados e quais não? O genérico "task failed" (sem mais detalhes) costuma ser transitório e pode ser retentado uma ou duas vezes; falhas determinísticas com code explícito (URL quebrada → INVALID_REQUEST, violação de conteúdo → CONTENT_POLICY_VIOLATION, parâmetro rejeitado pelo modelo) não se resolvem com retry e exigem alteração da entrada.

Minha tarefa fica em handling eternamente, nem falha nem conclui. Isso é timeout, não falha. Continue o polling ou aumente o timeout do cliente; veja Timeout de tarefa HiAPI e erro 504.

Recebi 400 / 401 / 402 em vez de taskId. Isso é rejeição da requisição — nenhuma tarefa foi criada, então não há "falha". Use os guias linkados acima para corrigir a requisição, a key ou o saldo.

Tarefas falhas são cobradas? Veja Requisições falhas da HiAPI são cobradas? para entender como a pré-cobrança e o reembolso são tratados em caso de falha.

Como confirmar que a URL de entrada está quebrada? Leia data.error.message. Problemas de URL geralmente indicam que a imagem ou o vídeo não pôde ser baixado; use curl -I para verificar se o link retorna 200 e é um arquivo de mídia direto.

Artigos relacionados

Ver todos os artigos →

Comece a criar com artefactos de IA persistentes

Obtenha a sua chave de API e chame modelos de imagem, vídeo e áudio através de uma única API baseada em tasks.

Ler a documentação da API