jackwener/OpenCLI · error · TimeoutError

Douyin transcode for video ${videoId}

Error message

Douyin transcode for video ${videoId}

What it means

pollTranscodeWithFetch polls Douyin's transcode status endpoint until encode=2 or the deadline passes; on timeout it throws this TimeoutError naming the videoId, meaning the video never finished transcoding within timeoutMs.

Source

Thrown at clis/douyin/_shared/transcode.js:31

/**
 * Lower-level poll function that accepts an injected fetch function.
 * Exported for testability.
 */
export async function pollTranscodeWithFetch(fetchFn, page, videoId, timeoutMs = DEFAULT_TIMEOUT_MS) {
    const url = `${TRANSCODE_URL_BASE}?video_id=${encodeURIComponent(videoId)}&aid=1128`;
    const deadline = Date.now() + timeoutMs;
    while (Date.now() < deadline) {
        const result = (await fetchFn(page, 'GET', url));
        if (result.encode === 2) {
            return result;
        }
        // Wait before next poll, but don't exceed the deadline
        const remaining = deadline - Date.now();
        if (remaining <= 0)
            break;
        await new Promise(resolve => setTimeout(resolve, Math.min(POLL_INTERVAL_MS, remaining)));
    }
    throw new TimeoutError(`Douyin transcode for video ${videoId}`, Math.round(timeoutMs / 1000));
}
/**
 * Poll Douyin's transcode status endpoint until the video is fully transcoded
 * (encode=2) or the timeout expires.
 *
 * @param page - Browser page for making credentialed API calls
 * @param videoId - The video_id returned from the confirm upload step
 * @param timeoutMs - Maximum wait time in ms (default: 300 000 = 5 minutes)
 * @returns TranscodeResult including duration, fps, dimensions, and poster info
 * @throws TimeoutError if transcode does not complete within timeoutMs
 */
export async function pollTranscode(page, videoId, timeoutMs) {
    return pollTranscodeWithFetch(browserFetch, page, videoId, timeoutMs);
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Increase the timeoutMs parameter and retry polling
  2. Verify videoId is correct and check the video's status manually on creator.douyin.com
  3. Re-check auth/cookies if status calls are failing so real progress is visible
  4. Re-upload the video if the transcode job is permanently stuck server-side

Example fix

// before
await pollTranscode(page, videoId); // default timeout
// after
await pollTranscode(page, videoId, { timeoutMs: 10 * 60 * 1000 });
Defensive patterns

Strategy: retry

Validate before calling

if (!Number.isInteger(videoId) && !/^\d+$/.test(String(videoId))) {
  throw new Error(`invalid videoId: ${videoId}`);
}

Type guard

function isValidVideoId(v) {
  return typeof v === 'string' && /^\d+$/.test(v);
}

Try / catch

import { TimeoutError } from './_shared/transcode.js';
try { await pollTranscode(page, videoId); }
catch (e) {
  if (e instanceof TimeoutError) {
    console.warn(`transcode still pending for ${videoId}; extending deadline`);
    await pollTranscode(page, videoId, { timeoutMs: 15 * 60 * 1000 });
  } else throw e;
}

Prevention

When it happens

Trigger: pollTranscodeWithFetch(videoId, ...) called via pollTranscode loops past the deadline because the video is stuck in transcoding (encode never becomes 2) or polling requests keep failing silently.

Common situations: Very large/long videos exceeding the default timeout; Douyin backend congestion; invalid videoId so status never reaches done; authenticated polling requests rejected so status stays unknown.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/f64ea4ccb6f82f84. Report an issue: GitHub.