DIYgod/RSSHub · error · Error

Details not found for product ${item.product_id}

Error message

Details not found for product ${item.product_id}

What it means

Generic Error thrown when, after fetching the product list and their details in parallel, a product_id from the list has no corresponding entry in the details Map. This is an internal data-integrity failure between the two upstream API calls — the list referenced a product whose detail fetch returned nothing.

Source

Thrown at lib/routes/mi/newproducts.ts:50

const getDataItem = (listItem: NewProductItem, detail: NewProductDetailData) =>
    ({
        title: listItem.product_name,
        description: utils.renderNewProduct(listItem, detail),
        link: `https://m.mi.com/commodity/detail/${listItem.product_id}`,
        image: listItem.img,
        pubDate: parseDate(listItem.start_time, 'X'),
        language: 'zh-CN',
    }) as DataItem;

async function handler() {
    const list = await utils.getNewProductList();
    const details = await getDetails(list);

    const items: DataItem[] = list.map((item) => {
        const detail = details.get(item.product_id);
        if (!detail) {
            throw new Error(`Details not found for product ${item.product_id}`);
        }
        return getDataItem(item, detail);
    });

    return {
        title: '小米上新',
        link: 'https://m.mi.com/',
        item: items,
        allowEmpty: true,
        image: 'https://m.mi.com/static/img/icons/apple-touch-icon-152x152.png',
        language: 'zh-CN',
    } as Data;
}

View on GitHub (pinned to bed535e087)

Solutions

  1. Retry the request after a short wait — this is usually a transient upstream inconsistency.
  2. If persistent, report an upstream API change to the route maintainer; the detail endpoint shape may have changed.
  3. As a route-hardening fix, skip products missing details instead of throwing (collect valid items only).
  4. Check Xiaomi's m.mi.com to confirm the product still exists.

Example fix

// before
const items = list.map((item) => {
    const detail = details.get(item.product_id);
    if (!detail) throw new Error(`Details not found for product ${item.product_id}`);
    return getDataItem(item, detail);
});

// after — skip missing details gracefully
const items = list.flatMap((item) => {
    const detail = details.get(item.product_id);
    return detail ? [getDataItem(item, detail)] : [];
});
Defensive patterns

Strategy: retry

Validate before calling

// Pre-check: ensure details Map covers all list ids before mapping
const missing = list.filter((i) => !details.has(i.product_id));
if (missing.length) { /* retry detail fetch for missing, or skip */ }

Type guard

function allDetailsPresent(list: {product_id: string}[], details: Map<string, unknown>): boolean {
    return list.every((i) => details.has(i.product_id));
}

Try / catch

try {
    const detail = details.get(item.product_id);
    if (!detail) throw new Error(`Details not found for ${item.product_id}`);
} catch (e) {
    // transient upstream gap — retry once, else skip

Prevention

When it happens

Trigger: utils.getNewProductList() returns items, getDetails(list) builds a Map keyed by product_id, and list.map finds an item whose product_id is not a key in that Map. The details API dropped or failed (silently) for that one product.

Common situations: Xiaomi's new-products API briefly returned a product detail that 404'd or returned empty; transient upstream inconsistency during a product launch; the detail-fetch loop swallowed an error for one item; product was delisted between the list and detail calls.

Related errors


AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12). Data as JSON: /api/errors/3881f52a9484d95b. Report an issue: GitHub.