nexu-io/open-design · error · Error

Vela video gen response is missing task_id

Error message

Vela video gen response is missing task_id

What it means

After submitting a Vela video generation request via 'vela video gen', the parsed JSON response lacks a non-empty task_id string. The submission is expected to return an object with task_id for subsequent polling via 'vela video get'. This fires when nonEmptyString(submitted.task_id) returns null.

Solutions

  1. Check the Vela CLI version matches the expected API contract
  2. Verify the workspace ID has video generation permissions and active quota
  3. Re-authenticate with the Vela CLI (vela login) if the session expired
  4. Inspect the full submit response JSON by adding debug logging around parseJsonObject
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const result = await renderVelaVideo(input);
} catch (err) {
  if (err.message.includes('missing task_id')) {
    // Submission failed — check Vela CLI auth and version, then retry
    logger.error('Vela video submission failed: no task_id in response', err);
    throw new UserFacingError('Video submission failed. Please verify Vela authentication and try again.');
  }
  throw err;
}

Prevention

When it happens

Trigger: The Vela CLI returns valid JSON without a task_id field; task_id is present but empty/null/whitespace; the CLI returned an error envelope that still parsed as a JSON object; API version mismatch where the response shape changed.

Common situations: Vela CLI version mismatch with the daemon's expected contract; workspace lacks video generation permissions; quota/billing exhausted and the CLI returns an error JSON without a task_id; session expired and the CLI returned an auth-error JSON object.

Related errors


AI-assisted analysis of nexu-io/open-design@5be4028344 (2026-08-12). Data as JSON: /api/errors/e4fa39d576f4789c. Report an issue: GitHub.

Appendix: source

Thrown at apps/daemon/src/media/vela.ts:471

      '--prompt',
      input.prompt,
      '--ratio',
      ratio,
      '--resolution',
      DEFAULT_VELA_VIDEO_RESOLUTION,
      ...(input.length == null ? [] : ['--duration', String(input.length)]),
      ...(firstFrame ? ['--first-frame', firstFrame.abs] : []),
      ...references.flatMap((image) => ['--ref', image.abs]),
      '--no-wait',
      '--json',
    ];
    const submitStdout = await runCommand(submitArgs, {
      ...velaWorkspaceCommandOptions(input.workspaceId),
      timeoutMs: VELA_VIDEO_SUBMIT_TIMEOUT_MS,
    });
    const submitted = parseJsonObject(submitStdout, 'video gen');
    const taskId = nonEmptyString(submitted.task_id);
    if (!taskId) throw new Error('Vela video gen response is missing task_id');
    lastStatus = nonEmptyString(submitted.status) ?? 'queued';
    input.onProgress?.(`Vela video task ${taskId} accepted; polling status ${lastStatus}`);

    while (Date.now() - startedAt < totalTimeoutMs) {
      await wait(Math.min(pollIntervalMs, Math.max(1, totalTimeoutMs - (Date.now() - startedAt))));
      if (Date.now() - startedAt >= totalTimeoutMs) break;

      const pollStdout = await runCommand(
        ['video', 'get', taskId, '--output', outputPath, '--json'],
        {
          ...velaWorkspaceCommandOptions(input.workspaceId),
          timeoutMs: pollCommandTimeoutMs,
        },
      );
      const task = parseJsonObject(pollStdout, 'video get');
      const returnedTaskId = nonEmptyString(task.task_id);
      if (returnedTaskId !== taskId) {
        throw new Error(

View on GitHub (pinned to 5be4028344)