jackwener/OpenCLI · error · CommandExecutionError

dongchedi ${contextHint} returned no __NEXT_DATA__. Dongched

Error message

dongchedi ${contextHint} returned no __NEXT_DATA__. Dongchedi likely changed its page structure, or the request hit an anti-bot page.

What it means

A CommandExecutionError raised in dcdFetchPageProps (clis/dongchedi/utils.js:94) when the fetched HTML contains no parseable `__NEXT_DATA__` script blob (extractPageProps returned null). Dongchedi is a Next.js app whose data lives in that blob, so its absence means the response was not a real SSR data page — either the site's structure changed or an anti-bot/interstitial page was served instead.

Source

Thrown at clis/dongchedi/utils.js:94

        resp = await fetch(`${DCD_BASE}${path}`, {
            headers: {
                'User-Agent': UA,
                Referer: `${DCD_BASE}/`,
                'Accept-Language': 'zh-CN,zh;q=0.9',
            },
        });
    } catch (err) {
        throw new CommandExecutionError(
            `dongchedi ${contextHint} network error: ${err?.message || err}`,
        );
    }
    if (!resp.ok) {
        throw new CommandExecutionError(`dongchedi ${contextHint} HTTP ${resp.status}`);
    }
    const html = await resp.text();
    const pp = extractPageProps(html);
    if (!pp) {
        throw new CommandExecutionError(
            `dongchedi ${contextHint} returned no __NEXT_DATA__`,
            'Dongchedi likely changed its page structure, or the request hit an anti-bot page.',
        );
    }
    if (isFallbackShell(pp)) {
        throw new CommandExecutionError(
            `dongchedi ${contextHint}`,
            'Dongchedi served its empty fallback shell — the id may not exist or the URL form changed.',
        );
    }
    return pp;
}

export function assertPlainObject(value, label) {
    if (!value || typeof value !== 'object' || Array.isArray(value)) {
        throw new CommandExecutionError(`${label} returned an unexpected payload shape; expected an object.`);
    }
    return value;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Open the same URL in a real browser and inspect whether `<script id="__NEXT_DATA__">` is still present — if not, the parser needs updating for the new page structure.
  2. If a challenge/anti-bot page came back, slow request rates, rotate to a residential IP, or retry later with fresh sessions.
  3. Re-run the request after confirming the 200 body isn't a cached proxy error page (bypass caches/proxies).
  4. Catch CommandExecutionError and distinguish this case from HTTP errors so users see 'page structure or anti-bot' rather than a generic failure.

Example fix

// before: assuming every 200 is a data page
const pp = await dcdFetchPageProps(path, hint);
// after: detect and degrade
try {
  const pp = await dcdFetchPageProps(path, hint);
} catch (e) {
  if (String(e).includes('__NEXT_DATA__')) reportLayoutDriftOrAntiBot(path);
  else throw e;
}
Defensive patterns

Strategy: fallback

Try / catch

try {
  const pp = await dcdFetchPageProps(path, hint);
} catch (err) {
  if (err instanceof CommandExecutionError && err.message.includes('__NEXT_DATA__')) {
    // anti-bot or layout change: back off, switch IP, or flag for parser update
    await coolDownAndFlag(path);
  } else throw err;
}

Prevention

When it happens

Trigger: Any dongchedi command when the server returns a 2xx response whose body is an anti-bot challenge, a CAPTCHA/verification page, an HTML error page, or a redesigned page without the expected `<script id="__NEXT_DATA__">` element (or with malformed JSON inside it).

Common situations: ByteDance's WAF serving a challenge to datacenter IPs or after bursts of requests; Dongchedi shipping a front-end rewrite that moves or renames the SSR data blob; a transparent proxy returning its own HTML error page.

Related errors


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