jackwener/OpenCLI · error · CommandExecutionError

Douyin API request failed (${method} ${url}): ${error instan

Error message

Douyin API request failed (${method} ${url}): ${error instanceof Error ? error.message : String(error)}

What it means

browserFetch executes a fetch inside the Douyin page context via page.evaluate and unwraps the result. If the evaluate call itself throws (page navigation, crash, CSP, script error), the error is wrapped in this CommandExecutionError including the method and URL. It signals the in-browser API request could not be completed at all.

Source

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

        if (!text.trim()) return res.ok ? null : { status_code: res.status, status_msg: 'Empty response body' };
        try {
          return JSON.parse(text);
        } catch (error) {
          return { status_code: res.ok ? -2 : res.status, status_msg: \`JSON parse failed: \${text.slice(0, 500) || String(error && error.message || error)}\` };
        }
      } catch (error) {
        return { status_code: -1, status_msg: String(error && error.message || error) };
      } finally {
        clearTimeout(timer);
      }
    })()
  `;
    let result;
    try {
        result = unwrapEvaluateResult(await page.evaluate(js));
    }
    catch (error) {
        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}`);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry the request; transient navigation/network errors are common
  2. Ensure the browser stays on a douyin.com page for the request duration
  3. Refresh signatures/params and confirm the endpoint is still valid
  4. Update the library if Douyin changed its API/CSP

Example fix

// before
try { result = unwrapEvaluateResult(await page.evaluate(js)); }
catch (error) { throw new CommandExecutionError(`Douyin API request failed (${method} ${url}): ...`); }
// after
try { result = unwrapEvaluateResult(await page.evaluate(js)); }
catch (error) {
  if (isTransient(error)) return browserFetch(page, method, url, opts); // retry once
  throw new CommandExecutionError(`Douyin API request failed (${method} ${url}): ${error instanceof Error ? error.message : String(error)}`);
}
Defensive patterns

Strategy: retry

Validate before calling

const onDouyin = await page.evaluate(() => location.hostname.includes('douyin.com'));
if (!onDouyin) throw new Error('browserFetch requires an active douyin.com page');

Type guard

function isFetchResult(r) { return r !== undefined && (r === null || typeof r === 'object' || typeof r === 'string'); }

Try / catch

try {
  const data = await browserFetch(page, 'GET', url);
} catch (e) {
  if (/Douyin API request failed/.test(e.message)) {
    await page.wait(2);
    const data = await browserFetch(page, 'GET', url); // single retry
  } else throw e;
}

Prevention

When it happens

Trigger: page.evaluate(js) throws — page navigated/closed mid-request, network error inside the page fetch rejected unhandled, evaluate serialization failure, or CSP blocking the injected script.

Common situations: Douyin SPA reloaded during the request; signed params stale after navigation; headless browser crashed; endpoint redirect triggering mixed-content/CSP failure.

Related errors


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