jackwener/OpenCLI · error · CommandExecutionError

Douyin API error ${code} at ${method} ${url}: ${msg}

Error message

Douyin API error ${code} at ${method} ${url}: ${msg}

What it means

Generic Douyin API failure: the response carries a non-zero status_code that is not classified as an auth error, so browserFetch throws CommandExecutionError embedding the code, HTTP method, URL and the API-provided status_msg/message. It surfaces server-side business errors (rate limits, invalid params, content policy) to the caller.

Source

Thrown at clis/douyin/_shared/browser-fetch.js:69

        throw new CommandExecutionError(`Douyin API request failed (${method} ${url}): ${error instanceof Error ? error.message : String(error)}`);
    }
    if (result == null) {
        throw new CommandExecutionError(
            `Empty response from Douyin API (${method} ${url})`,
            'The endpoint may have been retired or may now require signed parameters.',
        );
    }
    if (Array.isArray(result) || typeof result !== 'object') {
        throw new CommandExecutionError(`Malformed response from Douyin API (${method} ${url})`);
    }
    if (result && typeof result === 'object' && 'status_code' in result) {
        const code = result.status_code;
        if (code !== 0) {
            const msg = result.status_msg ?? result.message ?? 'unknown error';
            if (isAuthLikeError(code, msg)) {
                throw new AuthRequiredError('creator.douyin.com', `Douyin API auth/permission error ${code} at ${method} ${url}: ${msg}`);
            }
            throw new CommandExecutionError(`Douyin API error ${code} at ${method} ${url}: ${msg}`);
        }
    }
    return result;
}

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the embedded code/status_msg and look it up against Douyin's status code list to identify the business error.
  2. If rate-limited, back off and retry after a delay (minutes, not seconds).
  3. Validate the request parameters (IDs, titles, cover URIs) before re-issuing the call.
  4. Retry once for transient codes; report/persist the failure if the code indicates a permanent rejection.

Example fix

// before: blind immediate retry
const res = await browserFetch(page, api);
// after: handle non-zero status_code with backoff
try {
  const res = await browserFetch(page, api);
} catch (e) {
  const m = /error (\d+)/.exec(e.message);
  if (m && TRANSIENT_CODES.has(Number(m[1]))) {
    await sleep(60_000);
    return browserFetch(page, api);
  }
  throw e;
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

try {
  return await browserFetch(page, api);
} catch (e) {
  const code = Number(/error (\d+)/.exec(e.message)?.[1] ?? NaN);
  if (TRANSIENT_DOUYIN_CODES.has(code)) {
    await sleep(backoffMs);
    return browserFetch(page, api);
  }
  throw e; // permanent business error — surface to user
}

Prevention

When it happens

Trigger: result.status_code !== 0 and isAuthLikeError(code, msg) is false — e.g. rate limiting, invalid parameters, forbidden content, or transient Douyin server errors.

Common situations: Publishing too frequently triggers rate limits; invalid video/cover IDs passed to the API; content rejected by review; transient 5xx-equivalent status codes during Douyin incidents.

Related errors


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