jackwener/OpenCLI · error · CommandExecutionError

dianping citylist did not render any city anchors; cannot re

Error message

dianping citylist did not render any city anchors; cannot resolve Chinese city names

What it means

CommandExecutionError from lookupPinyinFromCitylist when https://www.dianping.com/citylist loads but the extracted map of city-name → pinyin anchors is empty or not an object. The library cannot translate Chinese city names to pinyin slugs without this page, so resolution of Chinese names fails hard. Typically the page was blocked, challenge-walled, or its markup changed.

Source

Thrown at clis/dianping/cityResolver.js:114

        );
    }

    RESOLVE_CACHE.set(lowered, cityId);
    RESOLVE_CACHE.set(pinyin, cityId);
    if (CHINESE_RE.test(raw)) RESOLVE_CACHE.set(raw, cityId);
    return cityId;
}

/**
 * Read https://www.dianping.com/citylist and return a Chinese-name → pinyin
 * slug map for every city link present on the page. Used when the user
 * supplied a Chinese name that isn't in the static map.
 */
async function lookupPinyinFromCitylist(page, chineseName) {
    await page.goto('https://www.dianping.com/citylist');
    const map = await page.evaluate(`(${buildCitylistMap.toString()})()`);
    if (!map || typeof map !== 'object' || Object.keys(map).length === 0) {
        throw new CommandExecutionError(
            'dianping citylist did not render any city anchors; cannot resolve Chinese city names',
        );
    }
    if (map && typeof map === 'object' && map[chineseName]) {
        return String(map[chineseName]).toLowerCase();
    }
    return null;
}

/**
 * Pure DOM extractor for /citylist. Walks every anchor on the page and
 * keeps the ones whose href matches the per-city slug shape and whose
 * text is a pure-Chinese label. Defined at module scope so the same code
 * can be exercised from JSDOM tests via toString() injection.
 */
export function buildCitylistMap() {
    const map = {};
    const anchors = document.querySelectorAll('a');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry — if it was a transient render/timing issue, a second attempt may render the anchors (add an explicit wait for city anchor selectors before evaluate).
  2. Avoid the online path: pass a pinyin slug or numeric cityId for --city instead of a Chinese name.
  3. Open dianping.com/citylist in the automation browser and screenshot the page to see if a captcha/verify wall is shown; solve it or slow down request rate.
  4. If markup changed, update buildCitylistMap in cityResolver.js to match the new anchor structure.

Example fix

// before
await page.goto('https://www.dianping.com/citylist');
const map = await page.evaluate(`(${buildCitylistMap.toString()})()`);
// after
await page.goto('https://www.dianping.com/citylist');
await page.waitForSelector('a[href*=".dianping.com"]', { timeout: 10000 }).catch(() => null);
const map = await page.evaluate(`(${buildCitylistMap.toString()})()`);
Defensive patterns

Strategy: fallback

Validate before calling

// pre-check citylist renderability
await page.goto('https://www.dianping.com/citylist');
const n = await page.evaluate(`document.querySelectorAll('a[href]').length`);
if (n === 0) console.warn('citylist empty — pass pinyin slug or cityId instead of Chinese name');

Try / catch

try { return await searchWithCity(chineseName); }
catch (e) { if (/citylist did not render/.test(e.message)) { return searchWithCity(PINYIN_FALLBACK[city] || KNOWN_CITY_ID); } throw e; }

Prevention

When it happens

Trigger: resolveCityIdAsync receives a Chinese name not in the static CITY_ID map, calls lookupPinyinFromCitylist, which navigates to /citylist and runs buildCitylistMap via page.evaluate — returning {} or null because no city anchors were found in the DOM.

Common situations: Dianping serving an anti-bot/captcha page at /citylist; page evaluated before content rendered; Dianping redesigned citylist so buildCitylistMap's selectors match nothing; network/proxy failure yielding an error page that still 'loads'.

Related errors


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