jackwener/OpenCLI · error · CommandExecutionError

Empty response from Douyin API (${method} ${url})

Error message

Empty response from Douyin API (${method} ${url})

What it means

browserFetch got a successful evaluate but the unwrapped result was null/undefined, meaning the Douyin endpoint returned an empty body. The library throws this CommandExecutionError with a hint that the endpoint may be retired or now requires signed parameters. It distinguishes 'request failed' from 'request succeeded but nothing came back'.

Source

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

        } 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}`);
        }
    }
    return result;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update the library to a version using the current signed Douyin API endpoints
  2. Verify the endpoint still works by calling it manually in the browser console
  3. Log in to Douyin in the controlled browser to restore full API access
  4. Regenerate any required signed parameters (X-Bogus/msToken) before the request

Example fix

// before
if (result == null) throw new CommandExecutionError(`Empty response from Douyin API (${method} ${url})`, ...);
// after
if (result == null) {
  const status = await page.evaluate(() => fetch(location.href, {method:'HEAD'}).then(r=>r.status).catch(()=>-1));
  if (status === 200) await refreshSignatures(page);
  result = unwrapEvaluateResult(await page.evaluate(js));
  if (result == null) throw new CommandExecutionError(`Empty response from Douyin API (${method} ${url})`);
}
Defensive patterns

Strategy: validation

Validate before calling

const raw = await page.evaluate(fetchJs);
if (raw == null) throw new Error('Douyin endpoint returned empty body; check endpoint/signatures before parsing');

Type guard

function isNonEmptyObject(v) { return v != null && typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length > 0; }

Try / catch

try {
  const data = await browserFetch(page, 'GET', url);
} catch (e) {
  if (/Empty response from Douyin API/.test(e.message)) {
    await loginDouyin(page);
    const data = await browserFetch(page, 'GET', url);
  } else throw e;
}

Prevention

When it happens

Trigger: page.evaluate returns null/undefined after unwrap — endpoint returns 204/empty body, response intercepted and stripped, or the in-page fetch resolved with no parseable JSON.

Common situations: Douyin retired an old public API; aweb-level changes requiring X-Bogus/_signature params that the script doesn't supply; geo/restriction returning empty payloads; logged-out session getting empty responses.

Related errors


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