jackwener/OpenCLI · error · CommandExecutionError

dianping search parser found result cards without shop_id va

Error message

dianping search parser found result cards without shop_id values

What it means

The dianping search parser extracted rows, but at least one extracted card is missing a shop_id, which is the required key for every result row. This indicates a partial or malformed extraction — selectors matched extra junk elements (ads, recommendation blocks, non-shop cards) or the shop_id attribute moved in dianping's markup. The library validates every row before returning to guarantee a consistent schema.

Source

Thrown at clis/dianping/search.js:143

        const result = await wrapDianpingStep(
            `search "${keyword}" extraction`,
            () => page.evaluate(`(${extractSearchRows.toString()})()`),
        );

        if (!result || !result.ok) {
            detectAuthOrPageFailure(
                { text: String(result?.sample || ''), url: String(result?.url || url) },
                `search "${keyword}"`,
                { emptyPatterns: [/没有找到|暂无结果|暂无商户|换个关键词|未找到相关/i] },
            );
        }

        const rows = (result.rows || []).slice(0, limit);
        if (rows.length === 0) {
            throw new CommandExecutionError('dianping search parser found no result-shaped shop cards');
        }
        if (rows.some((row) => !row?.shop_id)) {
            throw new CommandExecutionError('dianping search parser found result cards without shop_id values');
        }
        return rows.map((r) => ({
            rank: r.rank,
            shop_id: r.shop_id,
            name: r.name,
            rating: r.starClass ? Number((Number(r.starClass) / 10).toFixed(1)) : null,
            reviews: parseReviewCount(r.reviewsRaw),
            price: parsePrice(r.priceRaw),
            cuisine: r.cuisine,
            district: r.district,
            url: r.url,
        }));
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Update the CLI/adapters package to the latest version — this usually means dianping changed markup and selectors were fixed upstream.
  2. Save the raw HTML and check whether the offending card is an ad/promo block; adjust or filter selectors to exclude non-shop cards.
  3. Re-run with a narrower keyword that returns plain organic results to confirm it is markup-related rather than query-related.
  4. As a workaround, filter out rows lacking shop_id before the adapter's validation by using a lower-level parse function if exposed.

Example fix

// before
const rows = await search({ keyword: 'coffee', city: 1 }); // throws on ad card without shop_id
// after
try {
  const rows = await search({ keyword: 'coffee', city: 1 });
} catch (e) {
  if (String(e.message).includes('without shop_id values')) {
    console.error('dianping markup changed: ad/promo cards missing shop_id in results');
  } else { throw e; }
}
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeShopRow(r) {
  return r != null && typeof r.shop_id === 'string' && r.shop_id.length > 0;
}

Type guard

function hasShopId(row) {
  return typeof row === 'object' && row !== null &&
    'shop_id' in row && typeof row.shop_id === 'string' && row.shop_id !== '';
}

Try / catch

try {
  const rows = await search({ keyword, city });
} catch (e) {
  if (/without shop_id values/.test(String(e.message))) {
    console.error('dianping returned non-shop cards (ads?) — update adapters or filter selector output');
  } else throw e;
}

Prevention

When it happens

Trigger: Any search call where result.rows contains an entry without a truthy shop_id — e.g. dianping inserted ad/promo cards without ids into results, a selector now captures header/footer items, or the data attribute holding the shop id was renamed.

Common situations: Site A/B tests adding ad cards to result lists; scraping pages where sponsored listings appear first; stale adapter code after a dianping HTML update.

Related errors


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