jackwener/OpenCLI · warning · CliError

NO_DATA

NO_DATA

Error message

eastmoney returned no quotes

What it means

The quote request returned HTTP 200, but data.data.diff is missing or empty, so quote.js throws CliError NO_DATA ('eastmoney returned no quotes') with a hint listing the symbols requested. This means eastmoney answered but matched none of the provided secids.

Source

Thrown at clis/eastmoney/quote.js:85

    /** @type {string[]} */
    const secids = [];
    for (const s of raw) {
      try { secids.push(resolveSecid(s)); }
      catch (err) { throw new CliError('INVALID_ARGUMENT', `Unrecognized symbol "${s}"`); }
    }

    // Multi-stock in one call via ulist.np
    const url = new URL('https://push2.eastmoney.com/api/qt/ulist.np/get');
    url.searchParams.set('secids', secids.join(','));
    url.searchParams.set('fltt', '2');
    url.searchParams.set('fields', FIELDS);
    url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');

    const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0', Accept: 'application/json' } });
    if (!resp.ok) throw new CliError('HTTP_ERROR', `eastmoney quote failed: HTTP ${resp.status}`);
    const data = await resp.json();
    const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
    if (diff.length === 0) throw new CliError('NO_DATA', 'eastmoney returned no quotes', `Check symbols: ${raw.join(', ')}`);

    return diff.map((it) => ({
      code: it.f12,
      name: it.f14,
      market: marketLabel(it.f13),
      price: it.f2,
      changePercent: it.f3,
      change: it.f4,
      open: it.f17,
      high: it.f15,
      low: it.f16,
      prevClose: it.f18,
      volume: it.f5,
      turnover: it.f6,
      turnoverRate: it.f8,
      amplitude: it.f7,
      peDynamic: it.f9,
      priceBook: it.f23,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check each symbol: verify codes exist and are currently listed (the error hint lists the exact symbols sent)
  2. Add a market prefix to disambiguate, e.g. 'sh600000' instead of bare '600000'
  3. Test one symbol at a time to isolate the bad one — one bad secid can empty the whole ulist response
  4. Retry later if eastmoney is having a partial outage; curl the URL to inspect the raw diff
  5. Refresh symbol lists to drop delisted/renamed codes

Example fix

// before
quote --symbols="600000,999999"   // 999999 doesn't exist
// after
quote --symbols="600000"          // drop invalid codes; test suspects individually
Defensive patterns

Strategy: validation

Validate before calling

const KNOWN = new Set(['600000','000001','00700.HK','AAPL']); // your maintained universe
const unknown = requested.filter((s) => !KNOWN.has(s.toUpperCase()) && !KNOWN.has(s));
if (unknown.length) console.warn(`Symbols not in verified universe, may return no quotes: ${unknown.join(', ')}`);

Type guard

const looksListed = (s) => /^(?:(?:sh|sz|bj)\d{6}|hk\d{4,5}|\d{6}|us\.[a-z.\-]+|[A-Z.\-]{1,8})$/i.test(String(s).trim());

Try / catch

try {
  await runQuote(args);
} catch (e) {
  if (e.code === 'NO_DATA') {
    console.error(`No quotes for: ${e.hint ?? args.symbols}. Verify each code is listed and not delisted/suspended; try one symbol at a time.`);
  } else throw e;
}

Prevention

When it happens

Trigger: All supplied symbols resolved to secids that eastmoney does not recognize — e.g. delisted codes, wrong-market assignments (a SH code guessed as SZ), suspended symbols with no quote, or typo'd codes that still passed resolveSecid's pattern checks; also eastmoney returning empty diff during API degradation.

Common situations: Querying delisted or long-suspended tickers; typo'd 6-digit codes that are syntactically valid but nonexistent; requesting US/HK symbols while the specific market feed hiccups; stale symbol lists in automated dashboards after corporate actions (mergers, delistings).

Related errors


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