Los errores de Seedance se dividen en dos capas: una es el fallo de la petición HTTP, por ejemplo 401, 403, 400 o 429; la otra es una petición correcta cuyo trabajo termina en failed o expired. Dar por bueno un envío porque la interfaz devuelve 200 es el error de diagnóstico más frecuente al integrar una API de vídeo. El orden correcto de investigación es: mirar primero el código de estado HTTP, después el estado de la tarea y el campo error, y solo entonces cambiar el prompt o el modelo.
Este artículo desglosa los errores por tipo, explica causas, orden de tratamiento y ofrece un bloque de código reutilizable para gestionarlos. Las rutas, los nombres de estado y los criterios de cuota pueden cambiar con las versiones; en la práctica, se rigen por la documentación del sitio y la documentación oficial.
Nota: Seedance, Doubao y Volcano Engine son marcas de ByteDance y sus empresas vinculadas. Este artículo solo ofrece una explicación técnica y no implica afiliación ni respaldo. Las rutas y los campos de los ejemplos son solo demostrativos; verifica la documentación antes de llamar.
1. Distingue fallo de petición y fallo de tarea
| Síntoma | Capa | Causas habituales | Tratamiento |
|---|---|---|---|
| 401 | HTTP | Clave ausente, formato incorrecto, caducada | Corregir la autenticación |
| 403 | HTTP | Permisos insuficientes, modelo no habilitado, restricción regional | Revisar permisos y habilitación |
| 400 | HTTP | Parámetro fuera de rango, nombre de modelo erróneo, material inaccesible | Ajustar parámetros según la documentación |
| 429 | HTTP | Límite de concurrencia, velocidad o cuota | Retroceso, reducir concurrencia |
| 5xx | HTTP | Sobrecarga o fallo temporal del proveedor | Retroceso, cambiar de canal |
| failed | Tarea | Rechazo de moderación, problema de material, error de generación | Leer error, corregir el material |
| expired | Tarea | Tiempo agotado sin completar o sin recoger el resultado | Recrear la tarea, revisar plazos |
| Fallo de descarga | Resultado | URL caducada, autenticación, red | Volver a obtener o guardar el archivo |
Los logs deben registrar al menos la hora, el código de estado HTTP, el código de error, el nombre del modelo, el task_id, el número de pedido y el tiempo empleado. No registres la clave completa ni imprimas tal cual la URL firmada del resultado.
2. 401 y 403: revisa primero las cabeceras y la clave
El 401 indica que la identidad no se ha verificado y normalmente no tiene relación con la capacidad del modelo ni con el saldo. Comprueba en orden:
- Si
AuthorizationesBearer <key>; Volcano Ark usa la API Key como Bearer Token. - Si la clave contiene espacios, saltos de línea o comillas de más, y si la variable de entorno se carga realmente.
- Si la URL base y la clave pertenecen a la misma plataforma y a la misma región.
- Si la clave se eliminó, rotó o desactivó, o si el proyecto no tiene permisos suficientes.
- Si un proxy inverso sobrescribe o descarta la cabecera
Authorization.
El 403 suele ser un problema de permisos: modelo no habilitado, cuenta sin permiso sobre ese modelo, restricción regional o de cumplimiento. Para el 401 basta probar una clave nueva con una petición mínima; para el 403 hay que revisar en la consola el estado de habilitación y los permisos de la cuenta, y cambiar el código normalmente no sirve.
3. 429: límites de tasa, concurrencia y cuota
El 429 indica que la petición supera un límite de velocidad, concurrencia o cuota. Escenarios habituales:
- Varios servicios comparten una clave y se disputan la cuota.
- Lotes de tareas arrancan a la misma hora en punto y generan un pico de tráfico.
- Los reintentos no aplican retroceso y, cuanto más fallan, más envían, creando una tormenta de reintentos.
- Las tareas largas ocupan toda la concurrencia y las cortas tampoco entran.
El principio de tratamiento es retroceso exponencial con jitter aleatorio, reducir la concurrencia, separar claves por proyecto y escalonar los envíos. No reintentes en bucle sin retroceso; seguir enviando a alta frecuencia durante un 429 convierte el límite temporal en una avería continua. Si el negocio necesita concurrencia alta, confirma antes el límite de cuota y prepara un canal de respaldo.
4. 400: los errores de parámetros son la mayoría
El 400 suele localizarse directamente con el mensaje de error. Revisa especialmente:
- Nombre y versión del modelo: cópialos de la documentación, no compongas sufijos de memoria.
- Duración: los rangos varían según la serie; por ejemplo, 2.5 admite 4–30 segundos, 2.0 de 4 a 15 y 1.0 de 2 a 12.
- Resolución y proporción: confirma si el modelo admite 4K, 21:9 o adaptive.
- Cantidad de material de referencia: 2.5 permite hasta 30 imágenes, 10 vídeos y 10 audios; 2.0 tiene límites menores.
- URL de imagen o vídeo: debe ser accesible para la plataforma, no una dirección interna ni un enlace que exija inicio de sesión.
- Tareas de edición o continuación: algunos modos solo permiten duración automática y no aceptan segundos manuales.
- Entrada de audio: algunas versiones no admiten audio puro.
La forma más rápida es reproducir el error con el cuerpo de ejemplo de la documentación y volver a añadir tus parámetros uno a uno. Prueba después de cada adición para identificar el campo exacto.
5. Tareas failed y expired
Un envío correcto solo significa que la tarea entró en la cola. Los estados habituales de la consulta son queued, running, succeeded, failed y expired. En failed hay que leer el campo error: rechazo de moderación de contenido, material de entrada no conforme, imagen de referencia ilegible o excepción durante la generación son casos con tratamientos completamente distintos.
expired suele aparecer cuando la tarea supera el plazo de ejecución sin completarse o sin recogerse el resultado. En la documentación, execution_expires_after es configurable y vale 48 horas por defecto; el ID de tarea se conserva 7 días. Pasado el plazo, seguir sondeando no la recupera: hay que recrear la tarea. Si usas callbacks, ten en cuenta que un callback no confirmado en 5 segundos se reintenta 3 veces, y la interfaz de callback debe ser idempotente.
No intentes superar un rechazo de moderación cambiando unas palabras una y otra vez. Confirma primero la autorización del material, los derechos de imagen de las personas, los elementos de marca y la política de contenido, y decide después si vuelves a enviar.
6. Tiempos de espera y sondeo
Hay que distinguir tres niveles de tiempo: el tiempo de conexión del cliente, el tiempo de una consulta individual y el plazo total de la tarea. La interfaz de envío suele devolver el task_id con rapidez; lo que realmente tarda es la cola y el renderizado. Un tiempo de espera HTTP demasiado corto marca como fallo un envío normal; uno demasiado largo bloquea el grupo de hilos.
Se recomienda empezar con un sondeo de 5 segundos y aplicar retroceso gradual hasta 15–30 segundos, con un plazo total definido. Si hay callbacks, úsalos como vía principal y el sondeo como respaldo. No reenvíes inmediatamente después de un tiempo agotado: comprueba primero con el número de pedido o una clave de idempotencia si ya hay una tarea en curso.
7. Fallo en la descarga del resultado
Que la tarea termine bien no significa que tengas el archivo. video_url suele ser una dirección temporal firmada con vigencia limitada; si la guardas en la base de datos y descargas horas después, es habitual recibir 403 o 404. Tratamiento:
- Descarga en streaming a tu propio almacenamiento de objetos en cuanto la tarea termine.
- Reintenta la descarga por separado; no rehagas la tarea de generación.
- Verifica el
Content-Type, el tamaño del archivo y que se pueda reproducir. - No imprimas la URL firmada completa en los logs.
8. Ejemplo: gestión de errores con retroceso e idempotencia
El código siguiente separa envío, sondeo y descarga, y solo reintenta errores transitorios. Las rutas y los campos se rigen por la documentación del sitio.
import os, time, random, requests
BASE = os.environ["SEEDANCE_BASE_URL"].rstrip("/")
HEADERS = {
"Authorization": f"Bearer {os.environ['SEEDANCE_API_KEY']}",
"Content-Type": "application/json",
}
def submit(payload, max_retries=5):
# antes de llamar, consulta la tabla por número de pedido y reutiliza el task_id si existe
for attempt in range(max_retries):
try:
r = requests.post(
f"{BASE}/contents/generations/tasks",
headers=HEADERS, json=payload, timeout=(5, 30),
)
except requests.Timeout:
time.sleep(min(2 ** attempt, 20) + random.random())
continue
if r.status_code == 429 or r.status_code >= 500:
time.sleep(min(2 ** attempt, 20) + random.random())
continue
if r.status_code >= 400:
raise RuntimeError(f"{r.status_code}: {r.text[:500]}")
return r.json()["id"]
raise RuntimeError("submit retries exhausted")
def wait(task_id, deadline_seconds=900):
deadline = time.time() + deadline_seconds
delay = 5
while time.time() < deadline:
r = requests.get(
f"{BASE}/contents/generations/tasks/{task_id}",
headers=HEADERS, timeout=(5, 30),
)
if r.status_code == 429 or r.status_code >= 500:
time.sleep(delay)
delay = min(delay * 1.5, 30)
continue
r.raise_for_status()
data = r.json()
if data["status"] == "succeeded":
return data["content"]["video_url"]
if data["status"] in ("failed", "expired"):
raise RuntimeError(f"{data['status']}: {data.get('error')}")
time.sleep(delay)
delay = min(delay * 1.5, 30)
raise TimeoutError(task_id)
def download(url, path):
with requests.get(url, stream=True, timeout=(5, 120)) as r:
r.raise_for_status()
with open(path, "wb") as f:
for chunk in r.iter_content(1024 * 256):
f.write(chunk)
Este código evita a propósito reintentar 400, 401 y 403. Los errores de parámetros y de autenticación no se resuelven por muchas veces que se reintenten; solo amplifican los logs y el coste.
9. Reintentos, idempotencia y lista para soporte
Los reintentos solo sirven para errores transitorios: 429, 5xx y tiempos de conexión agotados. Los 400, 401 y 403, igual que un rechazo de moderación, no deben reintentarse automáticamente. La clave de la idempotencia no es el número de reintentos, sino el número de pedido: consulta la tabla antes de enviar, guarda el task_id después y reutiliza la tarea existente en peticiones repetidas.
Antes de contactar con el proveedor, organiza la información con esta lista:
- Registra la hora del incidente, el código HTTP, el código de error y el mensaje completo, con los datos personales anonimizados.
- Anota nombre de modelo, duración, resolución, proporción y cantidad de material de referencia.
- Anota task_id, número de pedido, número de envíos y número de sondeos.
- Conserva una petición mínima que reproduzca el problema, sin datos privados ni secretos.
- Distingue fallo de petición de tarea
failedoexpired. - Comprueba si la URL del material es de acceso público y si la respuesta es demasiado lenta.
- Confirma la cuota, la concurrencia y los permisos de la cuenta para descartar 429 y 403.
- Adjunta el ID de petición y la hora de reproducción antes de abrir la investigación.
Preguntas frecuentes
El envío devuelve 200, ¿por qué la tarea falla igualmente?
200 solo indica que la tarea se creó. La generación de vídeo es asíncrona; el estado final está en status y en el campo error de la consulta.
¿Un 429 significa saldo insuficiente?
No necesariamente. El 429 suele indicar límite de velocidad, concurrencia o cuota; un problema de saldo puede devolver otro error. Revisa primero la concurrencia, las claves compartidas y la estrategia de reintentos.
¿Se puede reintentar directamente una tarea failed?
Lee primero el error. Un rechazo de moderación o un material no conforme suele volver a fallar si se reenvía tal cual; un fallo de red o del proveedor sí admite reintento con retroceso. Antes de reintentar, comprueba la idempotencia por número de pedido.
¿Cada cuánto conviene sondear?
Empieza con 5 segundos y aplica retroceso gradual hasta 15–30 segundos, con un tiempo máximo total. Si hay callbacks, úsalos como vía principal y el sondeo como respaldo.
¿Qué hago si la URL del resultado no abre?
En la mayoría de los casos ha caducado o la firma ha dejado de ser válida. Guarda el resultado en tu almacenamiento en cuanto la tarea termine; si ya caducó, vuelve a consultar la tarea o recréala, en lugar de pedir repetidamente el enlace antiguo.
Siguiente paso
Crea primero una clave de prueba en la pasarela de IA de ZSQH y practica una vez cada caso: 401, 429, error de parámetros y tarea fallida, para confirmar que las alertas y la estrategia de reintentos funcionan. La disponibilidad de modelos y la forma de cobro se rigen por precios de modelos.
Lecturas relacionadas:
