{"record":{"id":"bcd5aca2b4230e17","repo":"DIYgod/RSSHub","slug":"no-article-url-found-for-article-with-id-id","errorCode":null,"errorMessage":"No article URL found for article with id ${id}","messagePattern":"No article URL found for article with id (.+?)","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"warning","filePath":"lib/routes/tailwindcss/utils.ts","lineNumber":36,"sourceCode":"export const fetchFeed = async (limit: number): Promise<Data> => {\n    const url = new URL('/feeds/atom.xml', BASE_URL).href;\n\n    const data = await ofetch(url, { responseType: 'text' });\n\n    const $ = load(data, { xml: true });\n\n    const items = await Promise.all(\n        $('entry')\n            .toArray()\n            .slice(0, limit)\n            .map((entry) => {\n                const title = $(entry).find('title').text();\n                const id = $(entry).find('id').text();\n                const url = $(entry).find('link[href]').attr('href');\n                const imageUrl = $(entry).find('link[rel=\"enclosure\"]').attr('href');\n\n                if (url === undefined) {\n                    throw new Error(`No article URL found for article with id ${id}`);\n                }\n\n                return cache.tryGet(\n                    `tailwindcss:${id}`,\n                    async () =>\n                        ({\n                            title,\n                            link: url,\n                            image: imageUrl,\n                            description: await fetchArticleContent(url),\n                            author: $(entry)\n                                .find('author')\n                                .toArray()\n                                .map((el) => ({\n                                    name: $(el).find('name').text(),\n                                    url: $(el).find('url').text(),\n                                })),\n                            pubDate: $(entry).find('updated').text(),","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/tailwindcss/utils.ts#L18-L54","documentation":"Thrown by tailwindcss/utils.ts:36 via `throw new Error(...)` (NOT an InvalidParameterError) when a Tailwind CSS Atom feed <entry> has no <link href=...> element. The route fetches /feeds/atom.xml, iterates entries, and takes the first link[href] as the article URL; an entry whose link elements lack href (or has none at all) triggers this. It is mostly a guard against malformed/partial feed entries.","triggerScenarios":"Tailwind's feed format changes; an entry is a non-article type (category/page) with no canonical link; the feed is partially generated or broken upstream.","commonSituations":"Feed schema change after a docs-site rebuild; a transient partial feed; a CMS-added entry that lacks a URL.","solutions":["Open /feeds/atom.xml directly and inspect the entry whose id matches the error message.","If some entries legitimately lack a URL, skip them (return null and filter) instead of failing the whole feed.","If the link moved to a different attribute/rel, update the selector (e.g. link[rel=\"alternate\"])."],"exampleFix":"// before\nif (url === undefined) {\n    throw new Error(`No article URL found for article with id ${id}`);\n}\n// after (skip entries without a URL so the feed stays up)\nif (url === undefined) {\n    return null;\n}\n// then: .filter(Boolean) on the collected items","handlingStrategy":"validation","validationCode":"// Filter entries lacking a usable URL before mapping.\nconst usableEntries = $('entry').toArray().filter((entry) =>\n  $(entry).find('link[href]').attr('href') !== undefined\n);","typeGuard":"function entryHasUrl($entry: ReturnType<typeof load>): $entry is ReturnType<typeof load> {\n  return $entry.find('link[href]').attr('href') !== undefined;\n}","tryCatchPattern":"// Wrap per-entry processing so one malformed entry does not fail the feed.\nconst items = await Promise.all(\n  entries.map(async (entry) => {\n    try {\n      return await buildItem(entry);\n    } catch (e) {\n      if (e instanceof Error && /No article URL found/.test(e.message)) return null;\n      throw e;\n    }\n  })\n).then((arr) => arr.filter(Boolean));","preventionTips":["Inspect /feeds/atom.xml directly when this fires to see the offending entry.","Consider skipping entries without a URL (return null + filter) instead of throwing.","Update the link selector if Tailwind moves the URL to a different rel/attribute."],"tags":["feed-parsing","upstream-change","tailwindcss","atom","wrong-error-type"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}